 So this is second breakfast, implicit and mutation based serialization vulnerabilities in .NET. I'm Jonathan Birch, I hack office for Microsoft. And if you wanna talk to me about this presentation, oh. I'm Jonathan Birch, I hack office for Microsoft. If you wanna talk to me about this presentation or anything else security related, please contact me on mastodon. In this talk, I'm gonna explain remote code execution vulnerabilities I found in several .NET NoSQL engines. I'll talk about what I'm calling a mutation based serialization vulnerability. I'll explain how you can bypass serialization binders and how you can defend against all of that. Also some bonus stuff just for DEF CON at the end. So a lot of my day job is doing security design reviews. I have a bunch of meetings every week where I'm looking at data flow diagrams telling people do it this way instead, that kind of thing. And something I do in those meetings anymore to sort of add value is I'll just open up the repo that I've never seen before and spend like a half hour while I'm talking to them figuring out what are the actual vulnerabilities here so I can talk to them about that too. And so the research that led to this talk happened because last fall I saw an article on a certain orange colored website about light DB and it's a .NET open source library for a NoSQL engine. I thought, okay, you know, I'll just go do a security review of their repo. And so when I did that, I saw this code and what jumps out to me in this code specifically is this line, this call to type get type that's being passed a string. And to me at least that's a really bad sign. But why is that a bad sign? So type get type in .NET is used to convert a string that's like the name of a .NET type into an actual type object. And what that means is that someone's going to be giving you the name of a type. Generally for an object you're going to create. So they're telling you what kinds of objects you're creating, which means they're telling you essentially what code you're going to run. And that means that if someone on malicious comes along and they give you a malicious type name and you're running malicious code. And so how does that show up in light DB? Well, light DB is a NoSQL engine and generally when an application is using it, it's just saying to light DB, store this object I've got and maybe at this index with these properties, that kind of thing. And what light DB is doing is it's going to put that in a file so it serializes it with a serializer called Beeson mapper into a Beeson stream and stores that Beeson stream in a file. And when the application wants the object back, it deserializes that Beeson back into an object again. So Beeson is just a binary encoding of JSON. So you can take that file light DB makes, decode it back into JSON. And if you do that, it looks about like this. And if you look at this JSON here, it's got this underscore type key in it. And after that it's got the name of an actual .NET type. So what light DB is doing with type get type is it's taking that type name, it's passing it to type get type to actually create the object during that deserialization. So the data in that Beeson is telling light DB what types it's going to make. And that means that this is just a polymorphic serializer behind the scenes. And that means it's got all of the classic vulnerabilities that polymorphic serializers have. But let's explain a little bit what I'm talking about there. So .NET serialization vulnerabilities. .NET serialization vulnerabilities generally happen because you have a polymorphic serializer. A serializer where the data is telling you what type it wants to be. So in this case we've got a box, it's some self-describing data. It says it's a cat, it's labeled cat. When your serializer sees that label, it says well I guess I'm making a cat object and it just makes a cat object and then sets some properties from the contents of that box. And the problem with this is someone malicious can come along and give you a box labeled pain. Your serializer says well I guess I'm making some pain then and you're having a bad time. So if you want a little more information in general on how .NET serialization works as far as for those sorts of serialization exploits, I suggest looking at the Friday the 13th Jason talks from Black Hat 17. But I'll also give you a few examples of what this pain is here. So in general what I'm talking about pain here, what I'm talking about is types that where if you tell an application to create them, they're gonna have side effects that can further exploit goals. Either when you call their constructor, set their properties, maybe their destructor, will do something that you want to have happen. Here's a couple of classic ones. Assembly installer has a path property. When you set the path property, it just calls load library on whatever path you give it. So if you've been able to drop a malicious DLL on a server somewhere, you're going to be able to do DLL injection. It turns out that if you give it an HTTP URL, it will actually go and request the file from that URL. It won't load it, but this is still really useful for getting pingbacks if you're attacking a server somewhere. Object data provider is sort of the more classic RCE gadget for a .NET serialization. It's got properties where if you set the properties on it, you can call any static method on any type in .NET with whatever string and integer parameters you want. So people usually call process.start just to pivot the shell injection. Okay, so that's how .NET serialization vulnerabilities work. Now I'll go back to LightDB and explain what I'm calling implicit serialization vulnerabilities. So here's a remote code execution exploit for LightDB. If you look at this JSON blob here, this is going to be the JSON we're going to put into LightDB. It's got that underscore type key where it's telling you what type it wants to be. It's going to be an object data provider. That's that gadget that lets you call any static method you want. We're going to call process.start and launch calc. And all we're going to do with this JSON is convert it to Beeson and then pass it into Beeson mapper to deserialize it. It's worth noting that when you call the Beeson mapper's deserialized method, you tell it what type you expect and it does not matter. So LightDB will actually respect the type the data says it wants to be. It'll go make it, it'll set its properties. Your serialization exploit gadget will run. It will then try to do a cast that will fail and probably throw an exception, but it doesn't matter. Your code is already run. So going back to how LightDB works. If you remember, LightDB uses Beeson mapper to read its own storage. So the problem here is that anything that can put malicious data in the database file can achieve RCE. It's also worth noting that when a client's using LightDB, they don't know they're using a serializer probably. They're almost never going to call Beeson mapper directly. So this is an implicit serialization vulnerability. The client is vulnerable to the serialization that's in LightDB, even though they're not using the serializer, LightDB is. And this makes that client vulnerable in a lot of ways. First of all, LightDB, when it stores the database file, it just stores a local file. So a lot of applications use LightDB just to write document formats or save files for games. So if you provide someone a document or a file that they're reading with LightDB, you can put an RCE payload in there and it will run code when they open it. LightDB is a NoSQL engine. It also has queries, which means you can achieve query injection and then you can put a malicious record in the database and when someone reads that record, you've got RCE. And there's one extra special exploit technique I figured out for this that I'll come back to. So what do you do when you find a remote code execution vulnerability in a major open source library? Well, you look at all the other libraries that are like it and find the same vulnerability there. So here is essentially the same vulnerability in MongoDB. So here is a JSON payload. It's got this underscore T key, that's the type specifier Mongo uses, that's T. Way the data says what type it wants to be. We're again making an object data provider. We're going to, again, call process.start and launch calc. And again, all we're going to do with this is convert it into Beeson and then deserialize it with the Beeson serializer that MongoDB uses. Now it's worth noting that you also tell the Beeson serializer what type you expect and that does matter. So in MongoDB, it will actually check that the type, the data says it wants to be, is assignable to the type it's expecting to get before it creates it. So if you want to exploit MongoDB, you have to find something in the data structure the application's expecting that's open-ended. So you can fit a serialization gadget into it. That said, it's almost always there. When I've looked at applications that use databases, there's almost always either an interface member on something or just a member of type object that's like a catch-all. And so you just put your serialization gadget in that slot and you still have RCE. Because MongoDB again uses this Beeson serializer to read its own database, it means that anything that puts malicious data in the database gets your remote code execution. MongoDB uses a client server kind of architecture most of the time. So you can have one malicious client that talks to the database, puts a bad record in there. Some other client reads that you're running code on that other client. You can also do, again, query injection. I will say that I was only able to exploit the .NET driver for MongoDB, not Java or Python. I won't say you can't, just that I couldn't figure out how to do it. And then we're gonna move on to yet another remote code execution vulnerability for yet another NoSQL engine. This one is RavenDB. So once again, we've got a JSON payload. This one, the type it says it wants to be is a Windows identity. Windows identity is a JSON .NET RCE serialization gadget. I suggest looking at Wiso Serial for details of how it works. But essentially it lets you pivot to a binary formatter payload which you then use to get RCE. And in this case, what we're gonna do with this payload is we're just going to actually make a connection to the database server and then do a port request to stick the JSON in the database. So RavenDB lets you interact with the database in two ways. You can read or write JSON to it or you can read or write objects from it. And so what you can do is if you put malicious JSON in the database and it's read as an object, that gets you RCE. Now it's worth noting here again that the type that's being expected matters. There's an assignability check like there was in MongoDB. And so you have to actually have some way to fit your payload into the expected types. This again is an implicit serialization vulnerability because RavenDB is using JSON.net with unsafe settings to read its own storage. So anything that puts bad data in the database gets you RCE. And that special attack pattern that I mentioned for LightDB works here also. And I looked at some things that were no SQL but not strictly databases. So here is a remote code execution vulnerability for service.redis. Service.redis is sort of a no SQL wrapper for a Redis cache. So here we've got some JSON. It says what type it wants to be. In this case it's saying it's going to be an assembly installer. That's the one that lets you call load library on an arbitrary path. We're just gonna say I dropped a malicious DLL somewhere for it to read. And then what we're gonna do with this JSON is we're going to stick it in the Redis cache and then read it back. So when we stick the JSON in the Redis cache as JSON, it's just JSON but when we read it back as an object using service.redis it's going to turn into whatever object we say it wants to be and it can run code. Now again, the type matters. So when you're using service.redis you tell it what type you're expecting and the payload you're using has to fit into the object graph you're going to have there. This is again an implicit serialization vulnerability. So because service.redis is using unsafe serializer to read the Redis cache, anything that lets you put bad data in the Redis cache also gets you RCE. And that extra pattern I keep talking about works here also and now I'm gonna tell you a little bit about how I discovered it. And that's because I was looking at one other NoSQL engine in .NET and that's MartinDB. So MartinDB like RavenDB uses JSON.NET with unsafe settings to read its own storage. But unlike RavenDB, it doesn't just let you write JSON. You can only read and write objects from the database. And when I tried to write an object to MartinDB that was just like a serialization exploit gadget would choke on it every time I tried. So I played with that a lot and I found a completely different way to attack it. And that's what I'm calling a serialization mutation attack. So here's a remote code execution payload for MartinDB. This one's a little bit different. So what I'm gonna do here is I'm gonna make in .NET a dictionary of string string. This could be a hash table too, but you need something that's got key value pairs mapping a string to a string. And what I'm gonna put in that dictionary is first a dollar type key paired with the name of a .NET type. In this case, workflow designer, which is another JSON.NET serialization gadget, it lets you do an arbitrary XAML read. Again, look at why so serial for details about how it works. And then I'm gonna do one other thing where I'm gonna set another key value pair where this is the name of a property on workflow designer, which is the one you set the XAML with to get an arbitrary XAML parse out of it. And what I'm gonna do with that is I'm just going to write it to the database. So if you write this object to the database and then read it back, that will run code, it will launch calc. And that's kind of weird. We're writing a dictionary to the database, but when you read it back, it runs calc. Why does that work? So this is using JSON.NET as its serializer. So let's look at how this works in JSON.NET. So in JSON.NET, if you serialize one of these dictionary string strings, like say you have a dictionary where you've got a key name fruit and the value pair, it uses the key names exactly as you provide them. So your key as fruit is just going to go into the serialized JSON as the key named fruit. Now, if you compare that to what an RCE payload looks like for JSON.NET, here's an example of one. You've got that type specifier key, that dollar type, and then you've got a .NET type name as a value for it and so on. And the key trick with this is there's nothing special about that dollar type key. There's nothing special about the type specifier used really in any of the serializers I've talked about. So you can make a key for a string string dictionary named dollar type and it turns out that if you serialize one of those string string dictionaries in JSON.NET or most of the other serializers I've talked about, it just uses the key directly. It doesn't filter it out even though it matches its type specifier. So what happens there is that you're essentially colliding with the syntax of what that RCE payload looked like. You're making it just output data where it's going to be the type specifier so when this object gets serialized and then deserialized, it mutates into a different type entirely and you can choose whatever type you want. And this doesn't just work for dictionary, it works for hash table, j object, expando object, and like 50 others, just go look around the .NET for things that have key value structures. And because of this mutation attack, you can do a lot of attacks on serialization that usually weren't considered possible. So say you have a website that takes some key value data and this is a screenshot from a certain website you might recognize that did not have this vulnerability but does let you enter key value data where you can choose both the keys and the values and you send that to a web front end with a form post and on the web front end, they're going to make like a dictionary or a hash table with the data you sent them and later on say that dictionary or hash table gets serialized to like a database or a cache and then later on after that, it gets read back from that database or cache using an unsafe serializer. Well, in that case, you can provide key value data where you're using that type specifier as the key name and when it gets read from that cache on some backend server, you can make it so it mutates into whatever object you want. It's now your serialization exploit gadget. It's now that pain and you've got remote code execution whenever that happens. So I was saying that was that extra attack pattern against all of these no SQL engines. Here's how that works against light DB. So light DB, you can make a dictionary string string. You put your payload in there. So you've got that underscore type key specified with a type name, in this case, assembly installer. So we're going to do again, a arbitrary called a load library. We're saying we're loading malicious DLL and all you do is you write it to the database and read it back. Now this hack is kind of magic. It doesn't matter where this is in the data structure. If you can control two key value pairs in some part of some object graph, if it gets saved and read back, that gets you RCE. And this actually makes a lot of attacks really ridiculous and easy. Like there's some application that's just asking you for a couple of string pairs and later you get RCE when it gets read from the database. And this kind of attack works with a lot of serializers. Here's a list of all the ones I know. These are all the dot net serializers I know where this sort of mutation attack works. You'll notice these are all JSON and BISN serializers. This doesn't work for binary formatter because it doesn't use anything like this kind of syntax. And it's also worth noting that this doesn't work against MongoDB's serializer. You'll note that there's different requirements for this to work in certain cases. Some of them you have to control the first key value pair. Some of them there's that assignability check. Some of them there's other like specific unsafe properties you've got to set. So there's a lot of variability in how exploitable mutation can be. For example, JSON.NET like most popular open source library in the world as far as I'm aware. You can get mutation attacks against it but it's a little bit tricky. You have to control the first key value pair because that's the only one it'll read the type specifier from. It has to be deserialized using unsafe settings. It has to be serialized in such a way that it doesn't double up the type specifier. And in general, I would suggest experimenting with this. There's a lot of weird special cases and nuances but sometimes you can make this work and you can use this to exploit things where the serialization is just not something you can touch. The serialization happens on the back end. You can't see the deserialized data. Maybe it even gets an H max stuck on it. It doesn't matter. On the other hand, there's serializers where this just works all the time. So if you've got JavaScript serializer with a type resolver, it will go out of its way to make the exploit work. It doesn't matter if you've got other entries in your key value storage. It doesn't matter if your type specifier is the last thing in the list. It doesn't matter if the assignability doesn't make sense. It'll just run the code and it'll just work. You can also do kind of a blind scanning technique to find these vulnerabilities. If you've got websites out there that you think are running on .NET and might have some back end cache or database, you can just stick key value data in there. You can use that assembly installer ping back trick I've talked about and you can wait to see if you later get a request back to your own server. So you can stick data in services blind, use maybe unique URLs for your ping back so you can see which one to talk back to you and then maybe later on when it gets read from the cache you'll get a request and you know there's an RCE happening there. You can defend and get these attacks in a bunch of ways. If you're writing an application, the best thing to do is don't use a polymorphic serializer and I'm gonna say that a lot in this talk. Don't use a serializer where the data gets to tell you what type it wants to be. If you have to for some reason, you can try using a serialization binder but I'm about to tell you how to bypass serialization binder is so kind of grain of salt there. So here's how to bypass serialization binders. In general, if you're talking about using a serialization binder for security purposes is acting like a filter. What's happening is during the serialization your binder is going to get asked about every type that's directly referenced in the serialized data and it'll say okay, this is the type I expect, go ahead or if you're doing it right you throw an exception when something type you don't expect shows up and that means if someone throws pain at you you say I don't know what pain is you throw an exception and nothing bad happens. So if you're doing it right your serialization binder looks sort of like this. What this is is just an allow list of all the expected types. It's a string allow list for both the assembly name and the type from the assembly name and if you see one that you don't expect you throw an exception. The problem is a lot of times people don't do this. Usually what you see for a serialization binder is something more like this where you have some assembly you've written yourself. You say well I trust all my types there's no crazy serialization gadgets in there. So if the type says it's coming from my assembly I'll just allow it and I'll use type get type to actually get the type out of there. And the problem with this approach is say your assembly contains a type like this. This is an initialized list type we're going to invent that just derives inherits from the just generic list type in .NET and we're adding another property to it. That seems pretty harmless but if you've got a type like this in that assembly that you're trusting you can export it like this. So here's a JSON payload to bypass that serialization binder I just showed you. The type it's saying it wants to be is initialized list that type I just mentioned but the type in the template for that is assembly installer that one that lets you do an arbitrary load library. The trick with this is initialized list is the type you're getting asked about that comes from your assembly so that binder is okay with it. And you'll notice that assembly installer is only ever referenced inside the template here but when this values part of the JSON blob gets deserialized it'll still make an assembly installer object it'll still set its path property and you're still doing load library so your RCE is still working. There's a trick here that when you serialize this with JSON.NET it'll put another dollar type entry in there for the assembly installer but you don't need it. It can figure out what it's supposed to be if it's not there so you can just take it back out again and then bypass the binder. There's another trick you can use to bypass serialization binders that I'm calling contagion. So, for JSON.NET and a lot of other BSIN and JSON serializers you've got that dollar type entry that's saying what type it's supposed to be but that object you're creating has members, properties, constructor arguments that have their own types and you don't have to specify the types of those in the JSON. If you serialize it, it will but if you don't the serializer will just figure it out. So if there's some serialization gadget you wanna use and it's a member of something that's a member of something that's a member of something that you can get past the binder you can use that one object that has it in its tree somewhere to get it past the binder. Here's one example. So, Windows Identity that I mentioned before is a JSON.NET RCE gadget it lets you pivot to binary formatter and you could have a serialization binder that specifically block lists that and if you do that you can still get it by. The way you do that is you use a Windows authentication event or ex-object. So if you serialize Windows authentication event args it has a constructor argument called identity whose type is Windows identity. So when you serialize that the only type going by the binder is this dollar type because the only things that the binder gets asked about are the types explicitly listed in the JSON. But when the identity part of it gets deserialized here it'll still make a Windows identity object it'll still set its properties you still get RCE. So that's a lot of problems. What if this has been fixed? So, I am with Microsoft I practice responsible disclosure I told all of these people about these issues in January or earlier. Everybody except MartinDB made some sort of fix MartinDB as far as I've checked last still hasn't. MongoDB's fix is pretty solid. I don't know how to bypass it they added a pretty strict allow list on the types that can get created during the serialization. It seems good. Everybody else here added a block list. LightDB also added an assignability check so that puts them about on par for MongoDB before they made a fix. I just showed you how to bypass block lists. I can bypass all of the fixes for LightDB, RavenDB and service.redis. Like I said MartinDB didn't get fixed. I told all of these people, look I can still bypass these fixes. They said we're not making additional fixes. So there's remote code execution vulnerabilities that are live right now for all of those libraries worth looking at. The mutation attack I mentioned against jason.net is not being fixed. I talked to James Newton King, the maintainer for jason.net about this. He said essentially it's supposed to do that. So that behavior is not going to be changed. If you've got some application that's using jason.net it might be vulnerable to mutation. Similarly JavaScript serializer, the .net serializer I mentioned that works really well for mutation attacks will not be fixed. I talked to the .net team about this. They said we tell people don't use JavaScript serializer. We tell people don't use type resolver. So we're not going to fix them. Just don't use them. So best practices to avoid these issues. First thing I keep saying, don't use a polymorphic serializer. Don't roll your own. It's a really bad idea. Don't have that data. Let you tell you what type it wants to be. It leads to all kinds of problems. Don't call type get type. Because if you're doing that you're probably writing a polymorphic serializer even if you don't realize you're doing it. Similarly in Java don't call class for name. Also remember that you can't use an unsafe serializer anywhere because mutation attacks. If it's on your back end, if you've got an HVAC it doesn't matter for mutation. You can attack like deep copy tricks. A lot of people use serializers to just deep copy objects. You can get RCE out of that because of mutation which is kind of silly. So don't use unsafe serializers anywhere. This one kind of hurts but maybe don't read untrusted data from NoSQL. Mongo might be okay but it kind of looks like every other NoSQL engine I've looked at. You can get RCE if someone can write bad data and you can read it back. Now I only really looked at .NET NoSQL engines but there's kind of a pattern here with NoSQL where they say just take this object and then later on you can tell the NoSQL engine I want the object back and I don't care what it is. Any time you have that pattern there's a polymorphic serializer in there somewhere and you can probably get RCE out of it. If you want a research project or want to go find libraries that are vulnerable maybe look at Java or Python NoSQL engines. Don't try to use serialization binders. It's possible to write a good one but nobody ever does it. Everybody screws this up. I see bypasses for these all the time. In general you're better off architecting your application so you don't need a serialization binder in the first place. And now I'm going to get into the bonus stuff that's just for DEF CON. So I've been talking about .NET framework exploits but what about .NET 6 Plus? Everyone seems to think that's different. It's not going to have these serialization vulnerabilities. So since 2016 .NET has had a couple of different flavors. There's .NET framework and then there's .NET. That's what they want me to call it but .NET 6 through 8. Those are the ones people use right now. All these exploits have been .NET framework exploits so they're the ones that are in YSO Serial. But what about .NET 6 Plus? Can you do this sort of stuff there? There is this myth that .NET 6 Plus is immune to serialization attacks. So here's the CVE Mongo opened for the vulnerability I found and it's kind of an eye chart there but I'll underline the important part here and what they said was it must be running Windows hosts using full .NET framework not .NET core. That's not true. Similarly if you look at YSO Serial they have a bug there which is is there any gadget for .NET core and no one has found one there. So admittedly exploiting .NET 6 Plus is harder. A lot of the exploitable types, the gadgets that people use in .NET framework just aren't there in the framework at all. There's also this whole issue where .NET, .NET 6 Plus whatever we're calling it actually divides the framework into three parts. There's .NET core, there's ASP net and there's the Windows desktop part. And depending on how you build your application you only get some of the DLLs that are even visible at all. So you can only use gadgets from the ones that are appropriate to how you built your application. So the ASP net core app types and the Windows desktop app types won't be found by type, get type. You can't deserialize them unless you've built with an ASP net app or a Windows desktop app. But you can still deserialization exploits. So object data provider is still there in .NET 6. It's still there in .NET 8. You have to have Windows desktop loaded for it to work but if it's loaded the payloads I've been showing you for object data provider they just work fine. There are also some serialization gadgets that do exist in .NET core app and now I'm going to go to the parts that aren't on my slides because I think I've got some time left. So I told you earlier how you can get a paint back with assembly installer. There's a similar trick you can do in .NET 6 in .NET 8 and so on and there's a few types you can use to do that. One of them is assembly dependency resolver. Another one is system.io.fileinfo. The trip with both of those is they will call create file whatever string you give them. So assembly dependency resolver has a constructor argument which is just a path and it'll just call create file on that path. The file info type you can set the read only flag on a file with it and you can do that however so you can also use that as a payload to do DOS because you can make files on the server read only but when you do that it'll also call create file on that path. Now there's a thing with create file in Windows where if you give it an internet SMB URL or a webdav URL it'll go talk to that. It's happy to do it. So if you've got an SMB server on the internet or a webdav server somewhere you can use those gadgets to get a paint back to that server. Now a lot of times if they're doing their offset correctly S and B outband will be blocked on the server you're trying to attack and sometimes the webdav redirector won't exist in the windows install. So it's a little bit iffy but in my experience usually one or the other of those works. So you can still get a paint back essentially by using assembly dependency resolver or file info setting the read only flag and then giving either an internet SMB URL or a webdav URL. And that's actually all I had. So are there any questions? Oh thanks I saw one over here. Sorry can you tell me that one more time? Sorry. Okay the question was do I have any examples of the vulnerable games? I don't remember which ones they are but what you can do is go on GitHub or like if you go on to NuGet. Okay so two approaches. Go to NuGet look at our projects that are dependent on light DB and then look at where those get used or just search on GitHub for uses of light DB for things that look like games. That's how I found a bunch of our examples of that before. Yes over here. Sorry. You said that after you're reading the object it will actually initialize the object injection right? So how did you find that in the first time? Because it's not something that you typically think about when you start this research. Okay to clarify was the question how did I realize that the vulnerability was there in the code that I was looking at to begin with? Yeah because you said I can control the key I can control the value and then when I read it it will initialize the object injection right? Oh okay so as far as that goes if you're looking for a polymorphic serializer where people are rolling their own which is a really bad idea in general what I look for when I'm doing these sorts of code reviews is calls to type get type that are just being passed a string especially if the string somehow comes from user data. Type get type being called on a user provided string almost always is either unsafe serialization or someone doing really sketchy with reflection invokes and both of those are probably RCE. Does that explain it? Yes it is, thank you. Okay in the middle here? Okay the question was did I look at DB? I did at least okay the question was did I look at DynamoDB NoSQL? I glanced at it. I did not do an in-depth test. It did not have as easy of an exploit as the other ones I looked at. I won't say it's safe. And then there was one over here? Okay the question here was the assembly installer exploit that I'm loading malicious DLL with and how can I make sure the malicious DLL is there present on the system? In that case the assumption is you've got some other exploit that lets you do a file drop. Something I should explain is the cases where I was using assembly installer exploits that's because the string is shorter than the object data provider ones. Object data provider works for all of these too so do lots of other .NET gadgets. Assembly installer I feel like honestly is more useful for doing a ping back to an HTTP URL because that lets you do that blind scanning I mentioned. And one way in the back you might have to come forward for me to hear you. So the question was whether automapper and fastmapper that also use that sort of reflection under the covers are also vulnerable. I'll admit I haven't looked at those. I'm honestly not quite sure what you're referring to so maybe we can talk a little bit more about it after this. If there's no other questions I'll finish there. Thank you.