
sorry hi I'm Stuart I'm a lead offensive security engineer um I.E red teamer and more more importantly I just sort of do Unix gymnastics from time to time and um also important to note I'm not affiliated with any of the companies or whatnot will be alluding to in the talk um standard set of disclaimers none of these views are my employers uh past present or future also if you're going to write the sort of things we're writing in here please um don't do that without thinking about who you're doing it against and and if you do my name that's my name I been mrar cool so uh that having been said sort of a where are we type thing um
this is us we could be red teamers pentesters blue teamers testing tools s admins testing the blue teams tools really anybody else um more practically we're the sort of people that see a Linux box and we're like huh we have access to this thing let's run a thing on it that sounds cool and maybe the sort of thing that's an elf binary it doesn't really matter but we'll for this um you know for this short amount of time we'll just assume we're running some sort of Elf binary on Linux box probably the sort of thing that maybe connects back to us and lets us do other things um the problem of course is that often there are things watching and
things they're like hey is this is this maybe questionable uh EDR or other things network analysis so on and so forth um EDR end point detection and response uh what we used to call antivirus and that then if it decides that we are malicious uh for some value of malicious we'll go rat us out to a sock analyst um or sometimes a SZ admin or whatnot who will then have a very awkward conversation with us saying like hey what what are you doing buddy ideally instead this happens where the um blue team tool is like no you're cool that's not malware or alternatively the sock guys is like oh NOP that's a false positive um or better both uh the it's a
benign program no bies um and and we'll be talking about small little changes we can make to hopefully make that happen quick plat twist um it is maybe not a common sentiment that you know you're just like share all the code you WR but I tend to do this with blue teams blue teamers who would like um I tend to go for things that the code will not catch not sort of the security bi obscurity don't want my techniques burned model um it's just a little little bit of philosophical rambling how this all works very briefly um each chunk of Mal or each process has certain things that you can observe argv the arguments or a file hash or
something that then gets sent to some magic box um and a vendor will tell you it's Wizardry AI ml behavioral analysis take your pick um often it's a static rule set Rex based or something like that that then will turn into some sort of alert that says oh no the bad thing happened holy cow uh which again rats us out to a sock analyst the idea then is to change something on our side to change some internal state of what's observed the observing thing to then change something in the internal state of whatever is observing us to then change something in the alert or maybe just prevent it from happening to eventually just cause the sock dude to
be like nothing okay that's cool um so then we can avoid those conversations so setup we'll have for the rest of the talk for testing uh very briefly is some Target or Target will be a Linux box um completely boring with notionally EDR that's less boring uh we'll just write a little reverse shell as a thing to hide um could be anything really but for us we'll just write a reverse shell with upload and execute via magic I I always hate to go to the talks and like oh here's a cool thing and you're like wait two steps back how did you get that on target demo magic and and we'll set ourselves a goal of stealing SSH Keys um
because we're stereotypes today here's our shell it's a single function single file program uh written go we'll start by connecting to our server and we'll take the oh no where's my little oh no there we go yes I'll start by connecting to the server uh we'll take our server address from the first command line parameter uh we'll read a file which we take from the second command line parameter and send it send it back to the server with a writing you know writing it the buffer out uh and then we'll spawn a shell and we'll just hook up this shell to our network connection and run it pretty simple um yes it's plain text uh we'll talk about that in a
bit and then on the receiving side it looks like this on this running side excuse me it looks like this uh we run it we give it the address and port to call back to that's the argv one or osar one um the file we want to steal which is our SSH key uh listen with netcat RL WP is kind of neat by the way for those who've not used it it gives you read lines so lefts and rights and control use and all that good stuff uh instead of just the typical net sh netcat shell um and then yeah we get a call back a call is received we see our key has been
exfilled that we asked for um give it a command process listing as one should when one pops a Linux box life is good and then there are a few things that can get us caught so number one is a scary name um and and process names for some value of name uh anyways can can actually cause problems I knew a young fellow who was just transferring some files and he thought it was funny and he named his python script lol. py and and the sock was like dude what are you doing you're not supposed to run League of Legends on your laptop um that was that was an interesting one he's like I don't know
what what um our domain could be malicious there are domains out there now that I I cannot connect to as domains um sensitive files can be a thing if if this process xfill and shell was not a trusted process to open this set of files that can trip alarms um and then PL Tex TCP sometimes is watched if you have the right tools to do it um I had a conversation with the CTO once about whether or not I should be running shell commands on uh over the network all right so they say that nature loves to hide we love to hide um and as we're hiding a few things to remember not all of this will work in every situation
you'll find that sometimes like you'll think oh this will get past one tool and then another tool will catch you but the good side is the flip side is um You probably only need one of these one or two of these tricks especially against Linux EDR um or something else and then finally um the only real way to know is to try it uh preferably with a sort of a purple team setup not a you know midnight like need to make screenshots and then and then somebody finds you not that I've ever done that um and then so for the rest of the talk we'll go we'll start with a few silly little things silly little 5-second changes you can
make that actually do work um we'll spend quite a bit of time talking about argv the command line parameters um and how we can change those and and that is the bulk of the way I've I've found myself um in somebody's Sim tool talk a bit about Network commoms how to hide ourselves a little with a minimum of work um not like super handroll perfect encryption just like minor changes and then a brief look at some system calls and how to avoid them maybe cool oh easy code changes all right so uh on these simple silly things you can fool EDR with this one simple trick there is actually a vendor who um was not happy to hear about this uh so
we take our our thing we used we see it's a couple Mega file surprise let's go we can just append random bites to it um and we can append 100 megabytes of random bytes uh and and we do that and we see it's now 103 megabytes and it runs just fine and um it turns out that everything that inspects a file has to have some limit on how much file it can inspect and if you go over the limit that just might ignore you I'd love to take credit for this I saw this in a tweet maybe 10 years ago and I still I can't find the Tweet but to to the guy who tweeted that thank you
it helped a lot um tldr big binaries not always in Ed properly um likewise every chunk of data you can take a hash with whatever hashing function md5 in this case um and you can also just append data to the file the date and time and and that changes your hash and now you suddenly have a different variant of the strain of malware totally undetected never before seen um you you'll know that you're getting detected by hash if your thing takes a couple seconds to start the first time and then the second time it's either really fast to start or really fast to not start that likely somebody is checking hashes against some database um and that works
and then third third TR different hash different M sorry uh third trick is a way to fool sandboxes not that I usually worry about this but I I sort of accidentally found this one day um I really just got lazy and forgot to check the length of the command line arguments that were passed that I passed to myself really um missed one missed didn't didn't remember to type it and then my malware crashed in the sandbox um and the sandbox was like oh you didn't do anything malicious cool perfect perfect tool um definitely not blasting SSH keys out everywhere so uh argument vectors the command line arguments you type in are probably the the number one way I found myself um not
being undetected uh briefly we have our Command we typed out looks like this and we can ask this file proc PID command line hey hey what are these the arguments and and it's obvious right it's like three of them there's there's this one and then this one and then this one and and yes um the file by the way is nby zero separated not new line separated um so we'll just translate new line or nulls into new lines it'll be easy and we see yes sure enough we have three arguments okay this is pretty obvious right um and this is what it looks like if we do a process listing I had a very long conversation with a
friend of mine who's a stock analyst like hey do you look at it like this or like this and he's like no actually usually when I do things it's just one string we reject on it it works um so I'm like oh that's a pretty good uh opportunity some observations Rex based detections are somewhat common um unless you're talking to a Salesman they're very common and rv0 is uh taken fairly seriously that's that's a lot more faith is put into that that L.P thing um once I once ran something and I called it Port scanner it was a port scanner I ran a port scanner we got a message back from uh somebody I forget
what I was like there is Port scanning on your network it's bad and and it turns out they just saw the word port scanner as rv0 and that was that was enough um if you want to test this in a in a situation try running curl with something that gets caught curl downloading a shell script piped sh or whatever and then try copying curl to girl and i' I've done this actually and um it worked pretty good I also knew a young lad who just was like okay here's what we'll do we'll just make a list of all of the bad commands and and find you that way um so if we can get around this
arvz thing probably WI and we laugh and we say oh wow man can they really do that and well you know you get on the box list the processes make sure they're not going to catch you uh how how often do you dig into those so it does go both ways um and and aside from arv there are many other ways to get your runtime config at you what to call back to what file to grab into your program that's sort of where we'll go with this um easiest way then is just to bake it into the source code all the programmers are like do you have to hard code things uh so this is what we did
and we have our arguments one and two zero of course is the name of the program asterisk for later and we can just change that nicely um set a couple variables at the top of the file because hard coding is not that great and then just stick them oops stick them where we would have stuck things from the command line compile it um cross compile it by the way go compiles nicely it's a BSD box we're using and by the way for those using go uh in such a context trim path is nice it gets rid of the bits of the path that like have your name in it um and we'll set some Linker Flags uh
specifically main do address which is why we stuck this in a variable so that at least at compile time we can configure it a little easier than having to edit the code every time uh set it to the address that we want to call back to same with the file then we can just run it but we can also run it and stick whatever we want in there and now we can be like oh no no these are benign arguments we won't get caught and and we can look and say yeah actually that that does hide us nicely dldr argv and source code means there's no argv to Rex on which is great except you have to recompile every time so
easier maybe as we'll uh we'll pass it from the environment uh we already used the environment a bit when we compiled our thing we set the environment variable Goos to Linux um and we can do this fairly simply in code if we take you know this what we had and just add uh some space and add an environment variable okay we'll just look for underscore address why not um and we will grab that key value pair the value in that key value pair and and try it and if if that's unset compare. or will default has to address which will get stuck into the address I this thing and passed on we can do the same with the
file Works nicely um building it now we don't even have to worry about coding like Linker flags and running it is uh exactly what you'd expect stick the address in the address and that will get stuck where it goes uh stick the file in the file that will get stuck where it goes run the program and it works nicely we don't have to worry about our command line the downside is uh we can look the processes environment and find out that well okay it is still a little visible but perhaps less so um it's it's friendlier to use and it's less um less noticeable uh of note EDR well not much is going to see this in a command line
well I'll see you running the command eh not really cool um in that case let's just take the arguments from standard input RV and air quotes from standard input uh um so that way it's not in our environment variables list uh so that's what we were doing we'll add ourselves a little space and then just we'll use format. f scan which will scan a file and the file just happens to be standard in and stick the first word space separated where in address the second in file um do some error checking we'll ignore end a file we'll ignore like there is no more standard in because that way we don't have to set a file we can just set the
address or set neither of them in default to the environment variables or hard-coded values air handling there's a few ways then we can get data into it into standard in um the obvious answer is just Echo it in with the obvious problem that now you're back to things on the command line you would rather not be um looks like that of course uh if you have bash you can you yes if you have bash you can use a he string not a he dock like we're used to but a he string uh with three left angle brackets which is the nice benefit that it's no longer in RV anywhere and it's no longer in a file or whatnot with the downside
though that you need bash uh which is not always guaranteed especially in containers of course you can just use a her do um as as as easy the downside for that by the way is it will make a very temporary file uh I think it's the file is made then UNL then written to but still there is a file cool tldr it's uh not even in proc pit Environ but it is kind of annoying to give up your standard in if you're writing a typical Unix filter type thing that you've uploaded to your target so we'll just take it from a file descriptor that's not standard in um it's almost exactly the same so we have standard in being
read and we'll instead of doing that Define ourselves a file descriptor number and standard in by the way is just file descriptor zero that's there's that's all it is and we'll just roll a new file abstraction over a file in the go world with whatever file descriptor we set and pretty much everything is going to be the same except we'll also just not worry if that file doesn't exist and that way we can be like config if we want it no config if we don't want it cool and then using it is almost exactly the same except you need to put a seven in various places like that and it works tldr we can take
a non-standard in file descriptor and use it to there is argv z um and I would like to point out there was a recent blog post about this that generated Some Noise online um this I wrote These before that blog post for the record um much like we're not pooping on anybody's EDR product or network traffic analysis product whoever not pooping on anybody's blog post uh for the record anyways we we normally run a program like this and we get AR v0 is the program name you don't actually have to do that it turns out if you have bash and I think zshell you can say hey make make whatever I give you rv0 um which also
answers the is this really the process name question and we can say use cargo pants why not that is our our argv Z now uh plus the program name to run and then whatever other arguments um and if you look at the command line now you have what you've set and you've taken what looked like malware and turned it into what looks like malware the collective groans of pain anyways easy change um instead of of our new file from file descriptor 7 we use uh uh a buffer with r zero with rb0 um one of the nice things about go by the way for writing this sort of thing is that you use a lot of interfaces so
scanf takes an io. reader not a file actually which is really just anything any type that has a method defined on it um so you can swap out things much like you go to the mall you swap out your your flipflops for shoes or whatever you can swap out a file descriptor for a buffer sure looks like this um exactly what you'd expect now rv0 has our two little things we've been configuring this whole time um and then our command line RGB Z has a space that's okay um and then if if tooling gives the the sock a single string for here's the command line it does actually kind of look differenter um if we look at a process
listing reg for our program it's not there look at a process listing GP for our domain name it is there but just looking at this and I would I would do the same it's like oh two arguments not really um you can still find the program by the way the actual binary that started it off with Pro pit exe and it looks like that um highlighting because colors did not show up very well TDR you can use arvz for arv for your input but really it's like don't do that it gets cooky okay so Network comes um as I mentioned I had this this discussion with the CTO at one point in my life about like whether or not I should put
certain things on the wire um if we look like look at ourselves this is about what would look like if we take a packet dump with TCP dump we see that uh yeah you see the connection you see the private key which is maybe not great as well you don't really want to put your company your client secrets in the wire and plain text um we can see the command ran and the output so it's very visible to anything doing deep packet inspection um and so we can just encrypt this uh to make us invisible ER you could write your own encryption if you really want I wouldn't I would instead with I think I
counted eight different characters changes um TLS IFI everything and and now we are invisible it is that different that easy to make the change one of the things I love about all this is like eight characters on our side change is like oh no and I I remember when TLS got easy like when let en Crypt came out and so on and it was there was a big like oh no what do we do now uh that happened um of course you need something to catch the TLs connection which means you need somebody to generate you assert or you use self sign one in the code for all of this um a GitHub link earlier we'll have it again
later uh little program that will grab you a tlser and um catch it catch your connection cool so less than 10 characters changed tldr uh adds TS and maybe Invisibles us but only sometimes um sometimes you have either TLS man in the middle which I guess we call TLS intercept if we want to sell things um and and that can be a little problematic at one point I was um we were working at a place and they're like okay SSH is bad SSH is used by hackers we're not allowed to SSH no more sshing and so I did the logical thing and I just dropped my ssh in TLS uh and then I wasn't sshing
anymore and then somebody decided oh no we need to man in the middle all TLS connections I was so I just wrapped it in HTTPS just added a like HTTP get and then SSH um changing to make to do that not terribly hard it's a little bit more work but um we'll use a nice pipe uh it's it's an abstraction you you stick things in the Right End you get things out of the read end uh not terribly much different than a Unix pipe um our connection now is no longer net. dial but HTTP poost will make a post request because post requests normally have large bodies or can anyways and the body will come from the read end of the
pipe cool and then uh sending back the file which we've read we just stick it in the right end of the pipe now our file goes into our post request and to the server and printed to our screen and then shell will spawn we need to get things back from the server so that's the body of the response the poster Quest responses from the server and output from the shell will go back into that same pipe so fairly you know simple two-minute change and now we have https you also get the nice benefit that you can go through a proxy because Go's HTTP Library sets proxies I think a lot of them do if you had the HTTP or https
proxy environment variable um also means that you can use sort of cloud-based load balancers I got sick of my domains being burned at one point and I was like okay I'm just going to use a whatever Cloud providers like API Gateway type thing AWS I guess API Gateway uh because nobody's going to block that work nicely all hdps TDR uh to use a not malicious protocol it's actually pretty easy another another single Digi is minute change um we do still have the problem though that DNS is not encrypted I mean yes it can be but we'll assume for the sake of argument it's not um so the simple answer there without going terribly deep into it is just don't do
DNS um in go this is how I would tell the HTTP Library um if this environment variable is set which was defined somewhere above you can believe me um if that's set okay then we'll just make a function that dials a an address in Port and stick that into our dialer thing um actually going through and reading the logic behind this is a little boring so we won't do that but take it for what it's worth DDR you can avoid DNS detections by avoiding DNS last thing we'll talk about system calls that are malicious um for somebody's definition of malicious uh file opens actually is one that I found it's not expecting but there are things
that are like okay this process and this file should not go together um as a sort of what it looks like under the hood we'll take cat and we'll read a the SSH key we've been going after this whole time and we'll we'll run this in bash with s trce so we can see like the the chain of um system calls at least the ones we're interested in and and we get bash starting sure we get cat starting as expected we get an open as expected and and from anybody looking we have Cat opening a file which is exactly what happened um and we can avoid this with one simple change file redirection so instead of Cat opening
the file if we'll do our our nice Tracy thing again we have bash starting uh we have bash opening the file and then starting cat and this actually is um in real life how I typically read files I just add a a left angle bracket one of these and I just don't worry about it anymore it's quite nice um we can put that in code to have code take input that way from standard in um by instead of reading the file into a buffer and writing it to a uh well the pipe from our HTTP thing we'll just copy from a a new file from whatever file descriptor we choose uh to that same pipe err handling looks like
this uh chose file descriptor 8 just because and instead of read from file descriptor the program opening the file it will read it from a file descriptor if we look at the system calls we have bash starting bash opens the file uh and changes to file script eight for us and then starts our program so as far as anybody knows we didn't open any malicious file we're just reading totally cool let the shell open files for you will save a little bit of work a little bit of conversation more than work uh without going into details at one point I was uh helping with an incident I I'm a red teamer but every so often they're like hey red teamer um
what do you think about this and and the question was Hey how do we take this this process that we're interested in and see what files it has opened and uh proc pit is the obvious answer um and and you kind of want to see something like this which means that it has no files open and presumably is not reading your SSH Keys which we've also seen is not always reliable uh instead we actually saw something like this something like this of course this is not real life and we're like oh that's that's not great two doors is open um for reading whatever it was in real life I couldn't even tell you um so so we
would like to maybe not be in this situation and the answer is to map the file into memory you'll still have it open for like a second but if uh the incident is being responded to or whatever um not such a big deal also for the EDR out there that pulls proc and and instead of using netlink or whatever it's like hey let's just look at proc every second or something um which happens uh it it can you can win that race so map file in memory uh it looks like this we'll start with that same thing we've been doing we'll send um a file into file descriptor 8 this time we'll send a whole hard drive so this is
a dis vda um and if we look yep it is open it's open for reading nice exactly what you expect uh all the other things are open true and and the core of it is we call M map and map it into memory the file for reading share is nice just takes less work um air handling we need the size we can get the size just by seeking to the end figuring out how big it is by the way if you're dealing with proc uh they have a zero by size often so don't use stat use seek um many minutes of my life for trying to figure out why I wasn't reading uh and then it
looks mapped and and proit Maps will tell you what's mapped into memory normally it's your your binary the shared object files should you have any go doesn't use any on Linux um and it is still visible but hopefully less likely to be seen um close the file scripture of course and then uh just just for the sake of something to do with it also because that was our goal we will use some reject which I defined like above in the code use some rejects uh and just grab you know buff through that buffer that we have M mapped we'll grab all the keys and just print them to our our writer our our pipe going back to the
HTTP server um don't forget to unmap the file by the way output looks like this got a call back got the connection we do see that we found a private key that we scraped off the disc um in real life you get a lot and it takes a bit um but it is an Nifty way to like once you have root figure out all of the keys deleted and undeleted ZR memory mapped files are easy to use CU you don't have to deal with reads and figuring out how big your buffer is and should you need two buffers CU you might have something on the split or whatever um and maybe not I'll just um Fork andec also gets caught I I
mentioned I was like midnight making screenshots and and what got me caught was um changing a time stamp so if we look at just this program we'll be using uh we can see that September 9th It Was Written Roots home directory was written SE September 7th so assuming I was on his route like hey something happened in the past couple days and and I did something similar to this uh I I touched the time stamps back to whatever his roote was um so it would look like this you know like hey no no no this wasn't this wasn't since whatever you're thinking of responding to no no this was old um and and then somebody was like
hey buddy what you doing uh and turns out something was like oh hey touch it was it was a Rex thing you know touch with an r with a a process or not a process a program name whoops uh and The Simple Solution is just to write our own code to do that so we'll use change times uh and we'll touch ourselves uh os. AR zero I'm sorry that was not actually a joke for the for the gentleman in the front row who's still snickering um we will change our own Tim stamp uh and and we'll just change it to a week before a negative offset um it looks like this when you actually run it so we list we uh started
at September 9th run the program it changes on time stamp to September 2nd one of the quirks of using ARG zero as what to change is uh if we have another file there say xfill and shell uh which was written slightly after this so presumably from you know in the minute after we landed we uploaded something sure uh we can use that exact minus a trick to set rd0 and change the time stamp of a different file kind of neat TI CIS calls may be less catchable than external programs last thing is is I two shells get away with a lot of things that um you're not meant to do uh i' I've seen like rule sets that's like okay this is
not supposed to happen unless it's sh or KSL or bash or whatever um we'll look at the interesting bits of this um and what we'll do is we will inject ourselves into the shell so the shell is running so it's I said I had this program named Port scanner that was a port scanner and and the sock was like not actually wasn't the sock but something else was like oh my God Port scanning what they didn't catch was that the shell was also Port scanning um obviously shell should be Port scanning things um they also didn't catch Port scanner. C next to it but anyways um and this is sort of how I did it you have to write slightly
differently um if you're going to inject the easiest way is to start your business end of the code in some initialization function or Constructor function um and just have that spawn a shell so in go it's go space or not a shell I'm sorry have that spawn a thread go space something um and it'll Fork a thread and do its thing and leave your victim process to go about its merry way um of course you also might want to run this as a standalone program so main is you know what starts at Standalone program it can't just call the Shell as well because now you have two from your init or Constructor function and Main
you don't want to do that unless you do maybe you do I don't know um and the easy answer in goand is to use a context which gives you two things a cancel which then what a cancel function which then uh says to anybody watching the CTX variable it done looks like this our shell will just whenever it's done hit the call this cancel function and then main will watch it so that may main won't exit before your shell is done um several hours of my life went to figuring out why my shell called back and then died very quickly uh and then last bit is you don't always get logging like you expect you can't just write the standard out
because who knows what standard out is parasti what your parasitized process is standard out will be um if you're not in a shell anyways which we won't be in a second so just open a file uh log log is set somewhere sure open a log file the catch with the error handlings there's not really much you can do if it doesn't work um kind of the whole point is you can't really get output very well so just bail um another another quick trick uh stick the PID in there in your log messages if you can it helps for debugging quite a lot um and so then when something goes wrong you can instead of log. fatal left die or
however you die stick in log file um preferably a file that nobody's going to notice uh using it then is not ter terbly different um or not using it sorry compiling it not terribly different uh the only catch is you can't really cross compile very well when you're doing this kind of thing it's it's a little different so uh my Linux build box just has an NFS share for all my source code so we don't have to deal with file transfers and such um we'll build it more like like we have we'll use for our file proc self command line so we can see what we're injected into make sure we got that right and then to build a
shared object file we can then shove into things uh build mode C shared um cool and that gives us now a shared object back good on the on the business side of this we have injecty lib we call it that I so we see it is a shared object file um and in bash the enable command will enable a shell built-in from a a library and if you don't give it a shell built-in name and a library name it'll just assume that the built-in it should call is the same name is the library um I always end my my shell built-ins witho but anyways and it'll wind at you that no no know it loaded
this library but there there's inject you.so struct or something it's not there I can't enable this function for you you messed up um but it did load it or open it at least and uh so yeah we got a shell back and we see it's hyphen bash not the bsh what we'd sort of expect um if we look if we grip around our own Shell's PID we'll see that yeah there's the shell well there's our PS in our our shell but it's parent what it's running in is Bash um and a nice little side effect if we look at our network connections it's bash not bsh that bash that made the network connection so our
our super scary shell here and it it does not have to be a shell you have bash do whatever you want like my port scanning um not making a network connection nothing to see there TDR inject code into known not malicious processes um shells get away with a lot EDR gets away with even more I did this once in a test environment just so I could see I did but it works you can totally just shove things into EDR as well um most do not have a user callable please load my library but uh if we just happen to have GDB oops UND happen to have GDB On Target uh we can ask GDB we
can hook it up uh to whatever our super duper EDR is or other victim process and just say hey please please call this libc function to open a library uh it will hopefully it'll whine at you but it'll still do it and then you get your your connection back and you can see yes we have in fact parasitized our super duper root proof EDR um super duper injection is super duper so that was cool what just happened tldr to all the tldrs uh number one Linux EDR will and other things observe a very finite set of observables um Rex is probably the rexon Ary specifically probably the number one thing to worry about and then we can get around that
with fairly small code changes that on our side are just not a big deal but on the other side the people watching us um can actually make a really big like oh no that is completely different difference um and third thing do it there's only one way to know if it's going to work is just to do it thanks um do we have time for questions yes time for questions and by the way that is me and the link to the source code for all of this and my apologies to anybody who tries to read the make file sorry all right no questions oh I'm sorry wait wait I I lied the gentle there was a gentleman in
the front row still snickering and totally distracted me oh good I'm
glad I I have never sat and say okay this Tech this not technique our side but technique your side will catch this and actually when I was originally thinking of this talk and putting it together I was like oh no I'll just find all of The open- Source Products I can and like compare them like Ah that's not really a nice thing to do like um so so short answer is I have no idea long answer is for from somebody who just gave a talk about BPF you're like so your m
yep yep yeah yeah and that's you know for every defense there is a countermeasure for every countermeasure there's a counter countermeasure um totally depends on where you are which is the last bit here the only way to know is to try it yeah good question though sorry I don't have an answer any other questions Andor Snickers all right [Music]