
good morning everyone this is breaking ground so you want to build a c2 uh before we kick off a few quick announcements as always like to thank our sponsors especially our diamond sponsors lastpass and palo alto networks gold sponsors intel google blue cat uh it's their support that makes this event possible uh because we are being streamed live please turn off your cell phones we do not have audience bikes in this room so raise your hand high after the talk and we will call on you uh and lastly uh just a reminder photo policy does not allow taking photos of other attendees and math should be kept on at all times with that please welcome i digital fan good morning everybody or afternoon as it feels like to me honestly uh welcome so so you want to build a c2 um so i'm going to talk about some crazy stuff that went through uh me building a c2 that is fully in use today kind of actually in the current ctf that's literally running right next door to us okay cool so give a little bit of background to myself um obviously i'm a security guy i love to program i love linux a lot i love windows really because i've been forced a lot of my life to work on it i'm creator of too many projects account and at my day job i kind of do more social security architecture stuff some offensive purple teaming things and i do a lot of work for prosv joe's so mainly i do a lot of work with the red team as you can see but also i do a lot of work with the gold team maintaining infrastructure and architecture and kind of doing system administration stuff there so stupid beginnings as i say every project starts with a stupid idea so we're going to take take us back to 2011 the dark ages of java a long time ago when i started college i was learning java as one of the programming languages you know in my stack that i know today and you know they say kind of laziness breeds innovation i kind of feel like it more breeds stupidity at least myself me being me i was really lazy and i wanted to encrypt data at rest and i looked at the implementation of aes in java and i said no screw that i don't want to do that that's too much so you know what i did i did the best thing possible i rolled my own crypto don't do that um it led to it's uh led to the invention of cbk which is a sort of lazy man's encryption um it stands for cipher block key it's like some like uh round cipher thing it's probably super duper insecure but i still listed on github so kind of going forward now um now it's like 2017. i started learning going uh because my work kind of wanted me to develop some projects that were kind of uh architecture and os independent so the the language at the time really to learn was go and i was like awesome so me being myself a person who kind of learns by doing i really needed a project to learn i needed something to do outside of my job like kind of the things i needed to do because i wanted to like dive into the actual stuff that go kind of provides so what i did is i revisited some old projects to rewrite um i ended up actually looking to cbk to rewrite i was like you know can i make this crap code run faster completely forgetting it's super insecure so uh we'll get to where that comes in but um so at the time currently i was doing a lot of red team development as well as most of my life in cyber security i was doing basically offensive stuff um now the thing was is while doing all this i never really found a tool that like worked correctly that really fit the needs that i wanted there was things that were missing like there were workarounds you had to do and they were like super clunky um things could be dependency heavy or you know the setup was like super annoying so you know that actually led me to a lot of the tools that i've you know built today there are some super c2-ish things that i've made like ws bind there's some like exploits and things i developed some of the things i've already previously talked on like in your mems which is a talk on antivirus evasion i've also made some utilities and i also made some stuff like kind of for trolling and shits and giggles realistically so that all leads to xmt xmt stands for the extensible malware toolkit so you might be asking what is xmt xmt is an offensive security framework it does a lot of malicious things really well and i say malicious things i mean like anything the miter attack framework may cover like you know dll injection assembly injection um you know processed doppelganging etc um and it provides c2 functionality and the only thing that's missing from that c2 functionality honestly is a user interface and what i mean by that is there's no button i can click to say do this i'd have to script all that out but everything else is still there the one cool thing that i made this with and i like an idea with is that it can be extended for any purpose so i leave a lot of room for users to input functions to change how it works to add things to extend functionality there's pretty much like anything you can extend it to like anything that really you can put your mind to encode uh the one good thing about it it's since it's go it's multi-platform multi-operating system so i've actually took some time to make sure that it supports and it works on every operating system and every os that golang currently supports in mainline but however sorry but however it's currently windows favored so meaning like a lot of the kind of the toys and the cool things in windows uh that it does support really only work on windows at the moment i'm adding some linux support as i go but some of those are kind of hard to do one to one and uh currently on the picture on the right well it's on kind of my right um that's the status of the repo as it is right now and currently we're at 32 000 lines uh as we speak so what did i want in xmd when i was developing it i kind of wanted to be easy to use i want it to be modular flexible i want to be simple at the same time so i wanted something to be you know configurable to an extent where it works out the box but also i could you know kind of change up how it works i wanted things to be not dependency heavy so i didn't want to rely on a lot of things and i also wanted to have a small build footprint you know i shouldn't have to spend time building my implants i should spend more time like popping boxes and throwing shells so kind of giving a quick list of the things that make up xmc i know it's a lot uh we have the overlying c2 package which contains like most of the c2 functions uh config transform wrapper we will actually talk about in the next slides uh there is also the task package which doesn't really make a super big appearance but it basically handles everything when it comes to tasking or uh you know if you want to create custom tasks for xmt to do then you have the cmd library which contains everything executable so like literally anything dsls assembly um you know etc uh the filter library the subpackage filter under it contains the cool filter um struct that we can use to literally select processes that we want to target so we can set parent processes or processes that own are like assembly or a dll et cetera and we have like cool things like setting the parent uh setting if it's like executable it's in a session or it's a service um like excluded processes etc then we have our communication library which contains most of our communication privilege uh primitives the limits library puts guard rails around some of the things we can do which is kind of cool then we have the pipe package which is actually a it's before the golang implemented name pipes and it's sublet it's standard library but this actually supports linux and windows and it supports setting security permissions on your pipes as well so you can do a lot more cool things with it wc2 is my own version of a web c2 are basically connections over http and we'll actually get into that as well data is just a package allows the right uh data primitives like any golang primitive it contains some like cool really util helper functions including some like memory buffers and such crypto same it's just some more cryptographic operation things device is actually one of the coolest packages and one of the largest it contains basically everything from interfacing directly with the device we're on so we have the evade package which does like defense evasion some other things like overriding hooks that might be placed in us by antivirus we have a local package that deals with identifying and detecting things on a local host we have the regedit package which is a high level interface for the windows registry then we have one api the window api registry and window api service when api is actually my own rewrite of the windows or the standard library windows package for golang and we'll talk about that one the registry package under is the same thing it's my rewrite of the golang register package and service is also again a rewrite man is the home of guardian and sentinel guardian is our sentinel is a loader for xmt and allows you to basically load it into like any process debate based on your rule settings like load it from like a http endpoint from a dll from a file and disk whatever guardian allows you to keep a singleton instance running current currently on the device and it will keep that instance regardless of you know what persistent mechanism you use so you're not like actually running a thousand implants on a host lastly of util it's just like a basic utilities directory uh contains some things we'll get into x error because it's a custom implementation of the errors package you go it does some really cool stuff that we'll get into bug tracks is a debugging library that allows uh you to to kind of log you know if the process crashes or anything super helpful text also contains a red regex free uh text matching algorithm and uh basically uh parser so you can do like some really cool textual expressions without all the bloat that the regex package in golang provides lastly we have crypt and i will talk about crypt in a little bit it's a sort of textual cryptographic helper that we'll get into that allows you to do defensive asian so i know that was a really long thing but i want to highlight now some of the things that actually and some of the interesting things that are actually take part into xmt itself so one of the first things if you're developing a c2 is identification it's like one of the most important things basically it's the process of getting to know our host device so it might be like the os version the architecture um the you know interfaces uh which and ip addresses it may have then also is basically generating unique identifiers that are unique to that host specifically as well as any environment info so like the username the domain it may be running under if it's windows and like your basic process and parent process id values for example and what this actually led me to is we ended up having to uh create our own ud uid library we originally used the machine id library but it seems it's abandoned now since like 2019 and unmaintained so we created our own which actually used some a little bit cooler features and used a better identification system in windows such as using the system sid instead of like the cryptographic hash of windows which doesn't change as much compared and is actually a little bit more unique and that actually led us to generating a 32-bit or 32-bit identifier which generates a 32-byte machine specific id called the signature and a three-bit instance specific call just a device session id and basically these like uh these 32 bytes generate this session id that's unique across every single host that you connect to so networking speaking computer now developing this i wanted to be super protocol agnostic and you know honestly the lazy man in me really didn't want to write code for like different types of connections uh you know i wouldn't be able to handle pretty much anything without having to worry about what the underlying connection is i didn't want to have to you know write workarounds for something stupid and i also wanted to make complex connections well easy i didn't want to like i wanted i wanted to have complex connections but i didn't want myself or like anybody else on the other end to have to deal with all the bull crap of like managing that connection like i don't want to have to anybody deal with that and what i ended up doing is these things now basically operate on the net.com interface which is just you know basic to go so networking so some of the things that do go into networking we actually actually took the uh idea and split it out into a thing called connectors and basic connectors are the simple interface that provides the ability to listen and or connect and it's defined actually in code by two interfaces which is one the connector it accepts a context and a string you want to connect to and then it returns like a netcon and or an error and the acceptor interface which gives you a you provide a contacts and a bind address that returns a net listener and or an error some can actually support both some are you know one some are the other but most of them do have support for both built in so and we have for built-in current support we have tcp udp ip icmp http https tls mtls and you know like i said before a lot of things you can create custom ones for this so the the ability for you to create custom ones you just have to basically implement these interfaces then there you go okay so one special highlight i did want to talk about is the udp connector so all connectors at least by default as you would think they're stream sockets so meaning you know we're not like basically we're not looking at packets we're looking at a raw data stream now if you know anything about udp udp is completely packet based same with ip and icmp for example and we really needed a way to support streaming over udp i really don't want to deal with edp on its own separate thing so i ended up working on developing my own custom udp listener and what this listener does is it contains its like own connection ring buffer and what that does is it maintains a active connections map and this will take new connections and pipe them back to uh like the accept calls or if it already has connection that we are currently mapping it'll take the data and push it into the current socket buffer that we have and it this makes internal like a heavy use of channels uh to work uh work on multiple go routines at the same time but it actually works up really great and it's like super rock solid like you could talk over this as if you were talking over tcp and you wouldn't know the difference um you know i've used this to like send like hundreds of megabytes of data and it just goes um you know which is really awesome and i ended up taking the success of this one and using struct inheritance for the ip icmp connector so now you can talk over ping or like any kind of you know ip based protocol as well the same way and with easy support so next one the wc2 connector the wc2 connector has the same problem as udp um you know it's http i didn't want to restrict just to post you know i didn't want to kind of send like a thousand post requests like every second that would be really suspicious so you know um i'm no stranger to web sockets and in fact i wrote the scoreboard over there which makes heavy use of websockets so i ain't no stranger to them but i was like man how can we implement these so i dove down into the code golang source code and it turns out golang will return some http bodies as read write if you play nice but you need really specific conditions uh one you need a 101 hd uh 101 switching connections uh response from server can't be http2 and the server must hijack that connection and you know this is kind of obvious when you think about like web sockets like underneath the hood this is kind of how they operate but you need to all do this all in like a custom way so that way you can basically jack that connection right out of there and what happened is we ended up having to use reflect in order to grab this because we needed like the direct neck con but we can actually index inside the supplied struct and we can just pull the connection out of there and now just use that as if we're talking overall tcp so some of the other things that i had to implement to like kind of improve in this area is during my offensive security kind of lifetime uh and some pen tests is that a lot of firewalls would block uh http connections based on like their cookie state and basically like if it's not it doesn't recognize it as like a real like web session because it would basically apply a cookie to that session over the proxy and if that session came back without that cookie you'd be like no i ain't accepting you so i had to make sure that we actually like worked on keeping session state inside as well and the other thing is we had to add actually proxy support for it uh golang doesn't have any windows proxy support at all um it has like next proxy support super easy it's all environment variable based um so what we ended up doing is and ended up implementing our own uh proxy function and we call it device.proxy and it's literally a one-for-one drop-in of the http proxy from environment function which is great so now we can use this for linux and or windows and it'll just work out the box um and this uses the one api i call uh when http get default proxy configuration which is basically it returns the either system based or gpo based proxy config on the host and we can parse out that data and then get like any of the proxy like what the http proxy your http exceptions etc and we just pull it out and now use it now the funnest thing i like to talk about the hardest one uh routing routing is really super complex and i hate that it is complex but the reason i made it complex honestly is because we need to support like a lot of feature sets some of the features we didn't need support would be like multi packets so if i'm sending data to a host and or like a command to a host and that's like one packet for example i don't want to have to wait for it to connect back to me again to wait and go send the other one like i can just send both of them at the same time like if it hasn't talked to you back why am i going to wait another time to send it another packet so i can send multiple all at the same time downstream device so we're not wasting any time then we want to also handle fragments um so if the packet's like too big you know we want to cut it up into bite slices for example because i mean i don't know about you but sending a pack a 100 meg dns packet doesn't look okay um then also there's a mode we created called channeling mode channeling mode basically allows you to break the normal like kind of weight back for a packet response from the client or the implant and now you can act as if you're directly at the terminal of the machine so it's like instantaneous feedback or instantaneous file uploads downloads etc so we also need to kind of have a work around that make sure that works correctly and last thing proxy connections or pivoting if you know if you're familiar with that nomenclature where we wanted to be able to piggyback off of other implants connections and this kind of led us down this huge you know rabbit hole of basically working on the thing of routing the identity and flags so to kind of uh give a button to that uh basically we use a struct called packet which is the huge basis of enterprise communication and it contains a thing called flags and device id basically flags are a boolean uh state of a packet as it flows through like the network to the actual final c2 server and it totes it notates the fragment size uh the fragment state as well so meaning like the group id because we can wait on multiple fragment