{
	"id": "624bb0e2-4384-4483-b371-a20ac13c86b8",
	"created_at": "2026-04-06T00:13:35.288665Z",
	"updated_at": "2026-04-10T03:19:58.194491Z",
	"deleted_at": null,
	"sha1_hash": "9c44b54afa829d13b0da0689fc654f1e304b3e09",
	"title": "Master of RATs - How to create your own Tracker",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 132818,
	"plain_text": "Master of RATs - How to create your own Tracker\r\nBy Danus\r\nPublished: 2020-04-27 · Archived: 2026-04-05 20:26:26 UTC\r\nMaster of RATs\r\nPreface\r\nOne day I was skimming through abuse.ch. This website collects user submitted malicious or suspicious URLs\r\nand I've stumbled through something very interesting. I saw that a user that goes by the twitter handle\r\n@Gandylyan1 is uploading huge amounts of daily samples of the same malware variant called Mozi (You can\r\nread about it here). This botnet is an IoT P2P botnet that seems to spread like crazy. Gandy is uploading samples\r\nas I write this article and there are currently 24,709 IPs uploaded to abuse.ch, and it seems gandy is the only one\r\nuploading them.\r\nThe malware is very interesting and not too complicated too understand. In the basic gist it spreads through IoT\r\ndevices using known exploits and brute forcing attacks, if it manages to connect to an IoT device it starts an http\r\nservice on that device and uploads itself to a random port and hosts the sample on the IoT device's IP address. This\r\npeer scans and attacks the network and when it takes over another device this newly infected device will receive\r\nthe mozi sample from the previously infected peer. This is a parasite. I was so excited about this that I've decided\r\nto set off with a simple goal in mind – to build a tracker for this botnet.\r\nBut alas my Linux knowledge can be summed up with the fact that I know that \" ls -la\" should print the contents\r\nof a directory. But the idea of creating a malware tracking tool was eating me up day and night. After a short\r\nsearch I've stumbled upon the following tool created by Intezer. This tool is found here\r\nhttps://github.com/intezer/MoP. This tool is a small python project allows a researcher to fake an infected malware\r\nclient by simulating an OS environment. All the researcher must do is reverse a malware network protocol. No\r\nhoneypots, no virtual machines no nothing. Sounds easy right? I though the same. I looked up any open source\r\nmalware tools on GitHub and found Quasar, which is an open source RAT which is used by people for malicious\r\npurposes. This is a great way to learn about malware, reversing open source malware and just understanding how\r\neverything works under the hood on the networking side. Great candidate for our little experiment! And so, I have\r\nset of to become the Master of RATs.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 1 of 30\n\nRequired Knowledge:\r\n1. Basic knowledge of Wireshark\r\n2. Basic knowledge of programming\r\n3. Intermediate knowledge in python\r\n4. Basic knowledge in C#\r\nRequired Tools:\r\n1. VMWare\r\n2. Visual Studio Community\r\n3. Python 3.8\r\n4. Sublime Text Editor 3\r\n5. Dnspy\r\n6. De4dot\r\n7. Brain\r\nSetting up some goals:\r\nBefore we even think about using Intezers tool we must reverse Quasar. What are we looking for?\r\n1. We want to understand how a Quasar client connects to a server\r\n2. We want to understand how Quasar constructs the messages it sends to the sever\r\n3. We want to understand if there is an encryption/decryption process for processing messages\r\n4. We also want to understand how the server processes client messages (which is possible in this case since\r\nwe hold the source code for Quasar)\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 2 of 30\n\nLearning to read C#\r\nWe load up the downloaded Quasar source into Visual Studio 2019 Community which can be downloaded for free\r\nhere and we are greeted with this:\r\nWe are interested in the client code, how ever just for reference and as we will be dealing with the others –\r\nCommon contains various utilities and Server contains the code for the Server application. All C# programs start\r\nwith Program.cs as far as I managed to figure out so we will start there as well, let's open Quasar.Client and find\r\nProgram.CS.\r\nAh, I wish this was C :frowning:. Anyway, we can see a few things of interest in this little statement if we right\r\nclick QuasarClient and then click on go to implementation we will drop on where most of the juice happens in\r\nthis code.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 3 of 30\n\nWe'll start by explaining the QuasarClient class which inherits from the Client Class. The job of this class is to\r\nmanage all the events that that accrue within the client, It has a special function to handle the registration of the\r\nbot ( OnClientState ), it has a function to handle message reading events ( OnClientRead ) and failing events (\r\nOnClientFail ).\r\nThe OnClientState function attempts to send an identification packet to the server. To explore how this message\r\nis created we can access the constructor of the ClientIdentification Class\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 4 of 30\n\nEverything here seems rather normal except for these Proto declarations.\r\nLet's get back to the Program. cs code block and look at ConnectClient.Connect\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 5 of 30\n\nWhich leads us back to the base Client class\r\nAlright! Seems like this the answer to our first goal! It seems that to initiate a connection the client first\r\nestablishes an SSL Stream, and then it looks like some sort of validation is happening using\r\nValidateServerCertificate callback and AuthnticateAsClient. Let's leave these for now as we are just mapping\r\nhow the code works. Now what happens next? If we access OnClientState through the Client base class that\r\nwould lead us to the event handler itself, to find the actual function that triggers on this even we must go to\r\nQuasarClient.cs and access the reimplementation of the function through there (Gosh I hate OOP). As we saw\r\nbefore, The OnClientState function triggers the client.Send function\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 6 of 30\n\nI'll be honest I don't know C# but I'm working with my instincts here (much like in assembly haha) and the only\r\nthing of value that I see here is ProcessSendBuffers so let's access that and see if it would yield us any results.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 7 of 30\n\nAgain, using the same strategy as before, lets access SafeSendMessage and see where it takes us.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 8 of 30\n\nAlright, now we don't want to access OnClientWrite as I fear it won't take us where we want but instead lets\r\naccess WriteMessage which is located within the class called PayloadWriter.\r\nJackpot. This function writes a serialized message(I'll explain what serialization is, don't worry) to the SSL\r\nstream! So, let's make a small diagram detailing our findings:\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 9 of 30\n\nAlright, this is obviously very shallow and incomplete and as we progress with our dynamic analysis, we could\r\nexpand on this diagram so let's compile this Quasar Project on Release settings in Visual Studio and move this\r\nentire thing to a virtual machine and start playing around with it.\r\nBuilding and analyzing a sample:\r\nAfter you compile Quasar and moved it to an isolated environment you can start the Quasar.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 10 of 30\n\nThis screen should pop up, and this is actually very important. This pop message is a builder for the X509\r\nCertificate which is responsible for creating a valid SSL stream between the client and the server. Quasar will\r\ngenerate a X509 cert and bind this cert to all generated clients. You can learn more about SSL here:\r\nhttps://www.youtube.com/watch?v=iQsKdtjwtYI\r\nAfter you generate a certificate is time to build a sample, after generating the certification click on the Builder and\r\nyou should be promoted with the builder menu, the most important part is this one:\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 11 of 30\n\nI have 2 IPs here; one is the loop back address and the other is the local IP of this Virtual Machine. I would\r\nsuggest binding the client to the IP of the current virtual machine as it would be possible to emulate connections to\r\nthe server from the current virtual machine and outside through the host (since the host is also a member within\r\nthe VMWare local network). You can use any port you like but I've used port 27015 because Minecraft. After you\r\nbuilt the client you should see it within the current directory of the installed Quasar client. Let's take it out and\r\nopen it in dnspy which is a .NET decompiler\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 12 of 30\n\nBut we are met with this garbage, but do not worry! We can use de4dot which a .NET binary de-obfuscator so\r\nlet's run it and we should be met with a clean Quasar client:\r\nSo what you can see here, is although our Quasar client is clean the symbols are gone but don't worry as we hold\r\nthe full source so let's start debugging. we just want to see if our diagram is correct so lets click start and place a\r\nbreak point on the entry point (I highly suggest renaming these functions and class names according to the source\r\nbut since I've debugged this so many times I already know this know block like my right hand). PLEASE MAKE\r\nSURE QUASAR SERVER IS RUNNING. We'll encounter our first problem with in Class0.smethod_3() which is\r\nthe second Initialization method:\r\nIt will not return True , thus causing the client not to execute and exit. but why?! Let's look inside our source\r\ncode:\r\nThis if statement which is marked in red, install and connects our client to the server by returning true after\r\ninitializing but it seems it will not execute as the current path the client is running from is not equal to the install\r\npath. To understand what I mean let's go back to the builder:\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 13 of 30\n\nSo, this code block checks if the client is currently being run from inside Appdata\\Romaing (In this specific\r\ncase) if its not there it would execute the following code:\r\nThis code handles two problems, one is that the client has detected that another instance of Quasar is running\r\nbecause it detected the same mutex that was used within the current client and the other is to Install the client into\r\nthe computer but adding persistence, killing and deleting the current file and process and relaunching it after it has\r\nbeen moved to our designated install folder. You can enter the Install method and read for yourself as the code is\r\nvery documented. This is very cool cause it gives a researcher a real insight in how malware might be developed.\r\nWith this knowledge in mind let's do two things:\r\n1. Update our diagram\r\n2. Move our client to the designated install directory and start it from there\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 14 of 30\n\nLet's debug our client from our preferred install directory and see what happens, remember to make sure the\r\nquasar server is running in addition I would like to fire up Wireshark to monitor the network(This are my own\r\nsettings, and the IP address and Port will be different on your machine):\r\nI'll restart the client from the Appdata\\Roaming directory and jump straight into the Client.Connect function:\r\nThis time we hit exactly where we want (Pro tip, you can right click dnspy objects and change their names\r\nbut hitting Edit method, after hitting enter to confirm the change it would send you inside the edited\r\nfunction – to go back, press backspace).\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 15 of 30\n\nWe have three places that are of value here, first is the RemoteCertificationValidationCallBack which would\r\nvalidate the certification received from the server, the stream reading function and OnClientState function that as\r\nstated before should send us to the QuasarClient registration handler.\r\nSo socket.Connect function should connect me to the server successfully and initiate the first TCP handshake :\r\nNext I want to examine what happens when we execute line 287.\r\nThis is an SSL handshake, but what happened is that the server passed its X509 cert to the client and the client\r\napproved this certification, and this is happening inside RemoteCertificationValidationCallBack. Let's examine\r\nhow it looks inside the source code\r\nAs you can see within the # else statement which happens when the binary is compiled with debug mode off, there\r\nis a function that checks if the clients and the servers certificate match. But look at what happens within the debug\r\nmode, it just returns true and because this happens on the client side… our client emulator can do the same to\r\ninitiate a valid SSL communication with the server. Let's keep this in mind and continue. What happens next is a\r\nbit tricky, in line 290 inside the Client Class, OnClientState would be called but because it is called from the\r\nClient class the event registration function would hit and not the event handler function.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 16 of 30\n\nWe must find the QuasarClient class manually and from there navigate to the OnClientState** function**(I\r\nadvise the reader to read this a few times and to play around with the source code to fully understand what this\r\nmeans as this is very important to understand how the client behaves, and having the source code is just a\r\nprivilege to expand on our researching and coding skills). \"But Danus! How will we find it in this mess of\r\nunnamed functions? \" The answer to that is very simple, let us return toClass0 which is Program.cs:\r\nSo Gclass27 is QuasarClient , lets rename it so it would be easier to navigate to it, then we'll access this class by\r\ndouble clicking it and try to find OnClientState Manually.\r\nDfyeA0y3IoaTpbrUvr7VKCJT3KvGcufsB_aubRnTGlaYNtWwCK2DX2Xiw0ZAsX7kvI1eZgHVcEesHk7dkRdT\r\nHere it is, let's place a breakpoint on line 79 , and set a breakpoint inside the PayloadWriter WriteBytes function\r\nwe found earlier which is located inside dnspy under Stream1, method02. On line 79 Class18 is created, and then\r\npassed into the send function. Class 18 is called ClientIdentification within the source code of Quasar:\r\nT_cm4zK80WAi5XFktdbGERi_u9hTa-xh6lN6a89jOhZSnP0tkv5iPZpDuIMJJS7mktlSGG_pKoj8FMMINyCUqafbSW2-\r\ng4PV1g9_tlCqhjk27PJTSOHC2kJ5uNwDyXT1CQup_Lrkfcd-XujsLg\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 17 of 30\n\nWhich is the message constructor and if we continue the execution up until the payload writer, we can see the\r\ncontents of this message:\r\nAnd we just intercepted the entire message. Easy. But how ever I do want to note something strange, there are\r\nonly 14 members inside the ClientIdentification class but here inside the debugged message there are 28?\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 18 of 30\n\nIn addition, in line 38 the message gets copied into a stream and serialized then the length of the message is sent\r\nand then the raw bytes returned from the serializer function are sent. What in the hell is a Serializer and why are\r\nthere 28 items in the message protocol when there should be only 14? Also look at the contents of the message\r\nafter it gets serialized. First let's debug the program until line 40 and view the contents of the array variable by\r\nright click it and then clicking on show memory window.\r\nOne can recognize some the message text but there are so many extra bytes here that just don't make sense at all.\r\nMessage Serialization and Google Protocol Buffer\r\nSo, to save the reader the time it took me to fully understand what the hell is going on here, serialization is a\r\nmethod to compress a message size and make its processing more efficient. Many types of serialization exist, one\r\ncan compress a message to a json format or an XML format and send it to a socket, the receiving side would de-serialize the message on a pre agreed protocol. You can learn about serialization here:\r\nhttps://www.youtube.com/watch?v=uGYZn6xk-hA\r\nQuasar uses something Protobuf which is developed by google, Protobuf Is also a message serializer (which I\r\nhope you know after watching the video I've sent above)\r\nAlright, this brings as to these ProtoMembers we saw earlier:\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 19 of 30\n\nThis C# class is defined under the ProtoContract which lets the compiler know that upon generating these 14\r\nmembers, to generate a google protobuf message with 14 members. That's why for each class member there is a\r\nproto member. Now the protobuf protocol compresses each type (int32, int64, string) differently and that's why we\r\nsee a lot of strange bytes in our message. This essentially answers goals 1-3 we set up before.\r\nIt's clear what we must do next:\r\n1. Create a python script that initiates an SSL connection\r\n2. Validate the connection between the client and the server\r\n3. Generate a protobuf message to match exactly the message that is sent by our generated client.\r\nImportant note on number 3, We can safely assume that the only important parts of the message are the Tag ,\r\nSignature and EncryptionKey members and from the tests I've conducted they must remain static and match the\r\ngenerated client exactly. Which makes sense as Signature and EncrpytionKey are the members which contain\r\ninformation from the X509 Certificate.\r\nLearning to write Pythonic Protobuf messages\r\nSo luckily for us, Google has made a programming interface for creating protobuf message with python and a\r\ntutorial which can be found here:https://developers.google.com/protocol-buffers/docs/pythontutorial\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 20 of 30\n\nI've crafted a message and script that initiates an SSL connection to our server:\r\nFirst the message is rather simple, it contains 14 members which match the exact same members in the Quasar\r\nclient. One can follow the tutorial I've linked on how to compile this message.\r\nThis little script creates an SSL socket and deals with the verification problem, by always returning 1 on each\r\ncertificate returned. This is cheating but hey, we are hackers :3\r\nNow to check our code, lets generate a message and serialize it. Remember that it must be appended with 4 little\r\nendian bytes that would represent the total size of our message.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 21 of 30\n\nSo, I've created a little function that would return exactly that and prefix it to the serialized message, now let's\r\ngenerate our message, serialize and print it and see if it matches to what Quasar generates.\r\nAs you can see, there is a problem with the first bytes. The message generated by python matches exactly (ignore\r\nthe prefixed size 0xdf 0x02 0x00 0x00) to the C# message besides the first three bytes. 0x0A, 0xCF, 0x05. What\r\nare these prefixed bytes? I didn't know so I've asked on stack overflow:\r\nhttps://stackoverflow.com/questions/61412249/protobuf-net-unrecognized-stream-prefix/61425656#61425656\r\nAfter a small research, I determined that this prefix can only be the length of the message. As the rest of the\r\npython generated message matches the C# generated python message exactly. In addition, if we edit the variables\r\nthe Quasar Client message is sending, this first prefix field would chance as we increase the length of our\r\nmessage. For example – lets debug our Quasar client instance again and break on the Payload Writer function at\r\nline 36 just before the message is sent and edit the message contents by adding an arbitrary amount of 'A'\r\ncharacters to one of the fields.\r\nAs you can see, the message was changed and from 0xcf the second byte turned to 0xf5. The difference between\r\n0xF5-0xCF is 38 decimal which is the exact amount of 'A' chars I've added. To craft this kind of integer length\r\nencoder we must first understand how this byte sequence is encoded and luckily for us Google won't keep that a\r\nsecret:\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 22 of 30\n\nhttps://developers.google.com/protocol-buffers/docs/encoding and in addition this was explained to me in length\r\nin the answer here https://stackoverflow.com/questions/61412249/protobuf-net-unrecognized-stream-prefix/61425656#61425656\r\nI won't go into detail explaining how this entire thing works, I've did that for my own self-interest (and I advise\r\nyou do that as well, @marcgravell on stack overflow explained it perfectly) but understanding this interferes with\r\nour main goal. Do we have to reimplement the entire thing from scratch when Google Protobuf is open source?\r\nThe answer to that is no.\r\nIn these two code blocks, I'm serializing a message and passing its length into a function I've \"Borrowed\" from the\r\nencoder script on protobuf GitHub. I've edited it a little bit by making it always prepend the 0x0A byte to final\r\nresult which represents the field number and field type. Since this message is prefixed to our generated message\r\nits always going to be of type 2 ( length prefix ) and field number 1 this combo will always yield byte 0x0A.\r\nBoom. Now our pythonic message matches the C# Quasar generated message.\r\nNow, on to the connection part:\r\nThis little code block will connect to our server and perform a handshake with it. Which will trigger the server to\r\npass its X509 certification, then our verification function will trigger:\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 23 of 30\n\nWhich will always return True. Then we're going to write our serialized message, prefixed with the length of the\r\nmessage + the length of the message serialized using this code block:\r\nFirst at line 97, I serialize the message. Then I append a prefix which represents the size of the message to the\r\nmessage. Finally, I calculate the entire size of the message including the prefix, convert the size to little endian\r\nbyte format and append that as well to the serialized message. The message is sent over to the server and we can\r\nview this inside Wireshark:\r\nAmazing! and if we check our quasar server, we can see that:\r\nI've sent a custom message that was registered with no problem! Now I headed out to learn how Intezers tool\r\nworks so I could turn my little test python script to a full Quasar RAT tracker.\r\nThe entire script can be found here https://github.com/DanusMinimus/Master-Of-RATs/blob/master/test_script.py\r\nCreating a Quasar Plugin for Intezers Master of Puppets\r\nThis part is a bit trickier as Intezer is not actively developing this tool, but I would go to length as to explain how\r\nthis tool works and save the hard work for you as I do believe this tool holds great value for tracking malware.\r\nMaster of Puppets is a collection of python scripts which allow to emulate a whole blown OS environment thus,\r\nsaving the researcher the time and resources needed to set up honey pots or virtual machines. Now the cool thing\r\nis that we don't need to set up a whole blown OS + Kernel and a boot loader as most malware would want to\r\ninteract with specific user mode applications and the file system and those are easy to emulate! How does it work?\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 24 of 30\n\nMaster of Puppets comes packaged with utilities scripts and handlers that emulate and deal with basic functions to\r\nhandle the malware such as connect, register, send, receive, and loop. The only job the researcher has is to create\r\nplugins for specific malware and the tool will handle the rest of the problems. I would like to walk the reader\r\nthrough the code and together create a diagram to help developers understand how this tool works. First download\r\nhttps://github.com/intezer/MoP and my custom plugins quasar.py, targets.yaml, utils.py and bring our also\r\npreviously created proto class from here https://github.com/DanusMinimus/Master-Of-RATs\r\nNext please follow the installation guide here https://intezer.github.io/MoP/docs/html/index.html\r\nIf you are using sublime text editor, you can click on Project-\u0026gt;Add Folder to project-\u0026gt;navigate to the\r\ndownloaded tool and this should open a comfortable view of the project.\r\nPlease open orchestrator.py and remove the first line \"#!/usr/bin/env python3.6\" as it causes the tool not to run on\r\nany version other than python 3.6. so, this is our main script for this tool. Scroll to line 46, as you can see this a\r\ncommand parser and in our case we'll be using the option described in line 53 – targets-config which allows the\r\ntool to connect to multiple clients, so please open targets.yaml and remove the hashes with in it.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 25 of 30\n\nI've already set it up to run with my instance of quasar but you can keep yours as is for now as we haven't set up\r\nour plugin yet. This tool sets up multiple targets, by specifying the IP, Port and the plugin for the target.\r\nIf we go back to the main script:\r\nWhat happens is at line 54, the targets.yaml file is parsed, and the contents of it are extracted. Then function\r\nconnect_targets() is called:\r\nWhich for each target found in the targets.yaml file executes the connect() function:\r\nThe connect function is found at line 22, it starts a thread with a callback function called _connect(), it passes the\r\nip, port and the plugin into this function. _connect is called at line 27. First it imports a plugin from the plugin\r\nfolder, then at line 29 it uses the plugin constructor to connect to the rat and then uses the plugins connect, register\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 26 of 30\n\nand loop functions. All the plugins that are created extend all the properties from the puppet_rat.py class. So, let's\r\nopen it up:\r\nG5Z4Wd9ZGhRbdKTIwlmlcpd4w6LnwrIDPgUk39M20yTAuouWwNRtxMD8oq6QKvEhH3BY0m0ZBNYTXle\r\n4nT7tMsG5nwVfPrLcvYhzueXrgmY9fsfjke9k0lNgym6fdVXDZs3ER3HRVALbHtCJQ\r\nAt line 16, we can see the constructor for this class which as we saw before at the main script is triggered in line\r\n29. Here at line 16 the constructor sets up various client attributes. The ip, port, the fake process id, the logger\r\nwhich is used to log all events and the conn variable which is used to represent a socket. The most important\r\nfunctions are:\r\n1. connect which is supposed to implement a connection to the server from the client.\r\n2. register which is supposed to implement the registration function\r\n3. loop which is supposed to mimic the infinite loop between the client which is waiting for orders from the\r\nserver client\r\nIt's clear what we must bring from our test script. First lets start with the easiest thing, let's edit the targets.yaml\r\nfile to match our needs. An example can be found in the images above. Next please download quasar.py and\r\nclientidentity_pb2.py from my repo linked above and place them inside the plugins folder.\r\nNow I'm going to review my plugin code line by line:\r\nFirst let's discuss the constructor which as you can see extends the PuppetRat class, thus inheriting all its\r\nproperties. I've added the message members so they can be edited on the fly. The only messages that a user has to\r\nset by himself are the Tag, EncryptionKey and the Signature as these interchange between client to client. In\r\naddition, I've added a protobuf message member called message which can be seen in line 70. It creates an\r\nuninitialized Quasar message.\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 27 of 30\n\nI've added 4 more custom functions that would allow the researcher to change the tag, id, key, and signature as he\r\nwould seem fit and function that would create and set a protobuf message. The function __del__ is a standard\r\npython function which executes when the object gets destroyed and in this case it would just close the socket\r\nconnection created for Quasar.\r\nThe re implementation of the connect function which is very similar to the one in the test script. Before we review\r\nit, please download the utils.py file from my repo and place it inside the stage props folder as I've added several\r\nfunctions to it. First in line 112 I create a tcp socket, then I bind that socket to a SSL socket and context. The\r\ncreate_ssl_sock is a custom functions ive added to the utils script. Much like in our test script all it does is create\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 28 of 30\n\nan SSL socket and binds a context to it so we can verify the quasar certificate. Then, a connect is started to the\r\nQuasar server and a handshake is attempted. If all goes well, the logger should display a proper message.\r\nThen we move on to the loop function, which is very primitive at the moment, all it does is receive messages from\r\nthe server and displays them.\r\nWe move on to the register function, which is the final one, all it does is mimic exactly what would test script\r\ndoes. It constructs a Quasar message and sends it to the server. I wouldn't go into length about this as we discussed\r\nthis already. Now finally, let's see how this run!\r\nStart your virtual machine and launch the Quasar server, then start a shell within the MoP project and input the\r\nfollowing command.\r\n\" py orchestrator.py –targets-config targets.yaml\"\r\nYES! Alright let's see what happens if we try to execute functions from the server itself by forcing the client to\r\nopen a message box:\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 29 of 30\n\nAmazing! As you can see, we received a new message which needs to be deserialized. This would require some\r\nmore effort into reversing more messages but from our gained knowledge it shouldn't be too hard :blush:\r\nThis sums up the post, I hope you enjoyed it! I'll try to release a full version for this plugin sometime so stay tuned\r\nand in the meantime happy researching!\r\nSpecial thanks to Intezer, Marc Gravell for this post as I probably wouldn't finish it without you.\r\nAnd thanks to my best friend x24whoamix24 as without your encourgment I would still be avoiding these pesky\r\nnetwork projects :slight_smile:\r\nSources\r\nSource: https://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nhttps://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848\r\nPage 30 of 30\n\n  https://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848  \nEverything here seems rather normal except for these Proto declarations.\nLet's get back to the Program. cs code block and look at ConnectClient.Connect\n   Page 5 of 30\n\n  https://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848     \nI'll be honest I don't know C# but I'm working with my instincts here (much like in assembly haha) and the only\nthing of value that I see here is ProcessSendBuffers so let's access that and see if it would yield us any results.\n   Page 7 of 30",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://0x00sec.org/t/master-of-rats-how-to-create-your-own-tracker/20848"
	],
	"report_names": [
		"20848"
	],
	"threat_actors": [],
	"ts_created_at": 1775434415,
	"ts_updated_at": 1775791198,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/9c44b54afa829d13b0da0689fc654f1e304b3e09.pdf",
		"text": "https://archive.orkl.eu/9c44b54afa829d13b0da0689fc654f1e304b3e09.txt",
		"img": "https://archive.orkl.eu/9c44b54afa829d13b0da0689fc654f1e304b3e09.jpg"
	}
}