{
	"id": "a89c1f3b-8f0a-4c7f-a99e-c8f0f38002a5",
	"created_at": "2026-04-06T00:13:49.0245Z",
	"updated_at": "2026-04-10T03:21:15.481168Z",
	"deleted_at": null,
	"sha1_hash": "dd11f95bff4d39a49fb78a1bb53965ef76de573b",
	"title": "Mars-Deimos: SolarMarker/Jupyter Infostealer (Part 1)",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 114618,
	"plain_text": "Mars-Deimos: SolarMarker/Jupyter Infostealer (Part 1)\r\nBy Binary Defense\r\nArchived: 2026-04-05 15:47:41 UTC\r\nNote: this post was originally shared on https://squiblydoo.blog/ by a member of the Binary Defense Team. In order to\r\nensure this research is visible to a broader audience, this employee agreed to let us share it here.\r\nSince the original post, the threat actor has been updating their malware and their tactics weekly. Some information in this\r\npost does not reflect the current version of the malware. However, the information is still important for defenders as there\r\nare still old infections that resemble the documented behavior, and the tactics can be used by other actors.\r\nPart One: Persistence Script Analysis\r\nMars-Deimos-RS-2.MD5: 88E60DFE5045E7157D71D1CB4170C073\r\nMars-Deimos-RS-2:SHA256: 8A57BD2598057EE784711B47B9B61B4ECBA5311FAC800B55070D560480F86EAC\r\nMars Deimos Overview\r\nMars-Deimos-RS-2 is .NET binary injected into memory. It has also been documented as Solarmarker by CrowdStrike. It\r\nshares Indicators of Compromise (IOC) with a directly related malware which has been documented as Jupyter Infostealer\r\nby Morphisec. The particular binary studied here appears to be tracked internally by the author as “Mars Deimos\r\nAppVersion RS-2”. Mars Deimos is a C2 client and the binary under analysis is the backdoor stage of the malware. The\r\nJupyter variant shares functionality with Mars Deimos but can also steal cookies from browsers.\r\nNote on naming: Though it can be confusing if there are too many names for the same malware, I want to maintain calling it\r\n“Mars Deimos” in order to assist defenders. In the original script, you can see it called “Mars Deimos” but I could not find\r\nany information about it under that name. In the Solarwinds analysis, it is called “D:M” by the malware author, so it seems\r\nlike the name “Mars Deimos” is appropriate to maintain. Jupyter shares some IOC with Mars Deimos, which can\r\ncomplicate things, but they are maintained independently by the malware authors and have different functionality.\r\nMy goal in this post is provide analysis of the persistence script. Because Mars Deimos is a present-day threat, it is\r\nimportant for administrators and analysts to recognize and understand the scripts if they are found.\r\nHow the Mars Deimos malware is delivered\r\nAccording to the analysis by CrowdStrike and Morphisec, Mars Deimos normally has several stages. The binary for this\r\nanalysis appears to be the fourth or fifth stage (according to CrowdStrike) and is the persistent backdoor. My analysis began\r\nat this stage and I do not have access to the earlier stages, but it appears that a user downloaded an executable that was\r\ndisguised as a Word document. The executable then dropped two files: a .bat script and an unreadable file without an\r\nextension. For persistence, shortcuts on the desktop were modified to call the .bat script.\r\nBeginning Analysis of Mars Deimos\r\nAs is common when PowerShell is being executed maliciously, the .bat script is written in a way to be confusing as follows:\r\nThe script was named “DZWhBTixXsCjSOuNobQfpImvelygwUznrLHGPtkFAaMKVYcJ.cMd”,\r\nthe script is all one line\r\nthe variable names are complicated (such as “$ab13e4b80f240fb13f8a62c3a6db5”).\r\nclass=\r\nImage of the Script before alterations\r\nTo be honest, looking at a script like this, it can boggle the mind quite easily.\r\nhttps://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1/\r\nPage 1 of 5\n\nFirst, we will break up the commands into separate lines. Looking at the beginning, we can see that it is using PowerShell\r\n(spelled “poWeRsHEll” to avoid detection methods that look for the word “PowerShell”) so we will break it at some of the\r\nsemi-colons to make it easier to read. (Some of the semicolons appear to be in a For-Loop, so we won’t break those up just\r\nyet.)\r\nclass=\r\nImage of the Script broken into sections to improve readibility\r\nThe script is still hard to read because of the variable names. At this point, the purpose of the variable in line 1 is unclear…\r\nbut in line 3, a variable is assigned a value from [system.io.file], and it appears to be getting the file from a “base64string”\r\nthat it is converting.\r\nThe easiest way we can convert that string from Base64 is using CyberChef: we can copy and paste that string into\r\nthe Input section of CyberChef, drag-and-drop “From Base64” into the Recipe section and then, see the decoded string in\r\nthe Output. In our instance, we receive a file path to a second file:\r\n“C:UsersUserNameAppDataRoamingbYtNoKkvyXglTMfAEaPreQVGbHpIFdzCjsfklSGPyQVrJqUXvMBuanNcODhwmxgLKiYWRtA\r\nclass=\r\nImage of CyberChef output after decoding Base64 input\r\nWith this information, we can conclude that a second file is being read into the variable on line 3,\r\n$a6eb2a91b614769b847e6964de33d. In the original incident response, a file was indeed found at that location and I have\r\nthat file. Let’s rename every instance of the variable name to $fileTwo since we don’t have much more information at this\r\npoint.\r\nclass=\r\nImage of script with the variable renamed to $fileTwo\r\nHaving renamed the variable, we see that after it is assigned the bytes of our second file in line 3, the variable is used a few\r\ntimes in the For-Loop and after the For-Loop, $fileTwo is loaded using [system.reflection.assembly]::load($filetwo).\r\nNext, we clean up the For-Loop to make it more readable. For Loops usually initialize a variable for use in the loop (an\r\niterator variable), create a condition that that is checked to see if the variable should continue, and then (optionally) a call to\r\nincrement the iterator variable. Typically when writing a program, one uses “$i” for the iterator variable in a For-Loop; if\r\nthere are multiple loops, the programmer names the next iterator “$j”. Since we appear to have two For-Loops, we’ll rename\r\nthe variable in the first For-Loop, “$ad066d1ff554189be1555e5c01765”, to “$i” and the variable initialized in the second\r\nFor-Loop, “$ac07982da3749c86bd16117fb94f0”, to “$j”. Also, while we are at it, we will format it to look like a normal\r\nFor-Loop.\r\nFor-Loop variables renamed and formatted for structure.\r\nFor someone familiar with For-Loops, that is much more readable now. The remaining obfuscated variable matches the\r\nvariable from Line 1 in the script. In the For-Loop, we appear to be indexing into and manipulating $fileTwo using “-bxor”\r\nand indexes of the obfuscated variable. (To use “bxor” is to use the XOR operator on the individual bytes. Explaining XOR\r\nis beyond my goal here. However, “bxor” is common in malicious PowerShell so the reader should take note.) So it appears\r\nthat the variable, $ab13e4b80f240fb13f8a62c3a6db5, is a key for decoding $fileTwo before loading it in line 7. So let’s\r\nrename the variable to “$key”. Having made those changes, the script is much more readable.\r\nclass=\r\nImage of the Script with obfuscation removed\r\nhttps://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1/\r\nPage 2 of 5\n\nLooking at the script now, we can see:\r\nThe script uses “CMD /c” to execute a PowerShell command with the Window option of “hidden”. (Line 1)\r\nIt sets a variable as a key (Line 1)\r\nIt sets a variable for a second file (Line 3)\r\nIt decodes the file using the key and two For-Loops (Lines 5-11)\r\nIt uses [system.reflection.assembly] to load the file (Line 13)\r\nAnd then “interacts” with the file it now calls “[mars.deimos]” (Line 13).\r\nHaving deobfuscated the script, let’s understand better what it is doing.\r\nUsing Google and searching for things such as “System.Reflection.Assembly used in malware” returns many results\r\nexplaining that this is a method of loading .NET executable into memory.\r\nPutting what we’ve learned together: the binary gets loaded into memory whenever this script is called. In order to make\r\nsure the script is called, an earlier stage modified desktop shortcuts to call this script. Great. Now let us find out what the\r\nexecutable does in order to understand risks and possible damages.\r\nWriting the binary to file\r\nInitially, I struggled finding a method of writing this binary to disk. While [system.reflection.assembly] has a load function,\r\nit didn’t have any obvious method to save the assembly as a file rather than loading it into memory. The articles I found\r\ndiscussed how to load assemblies into memory and did not focus on analyzing assemblies that were loaded into memory. So,\r\nI want to document my solution here as well.\r\nIn this situation, we have access to the script that loads it into memory, additionally, the script itself does the decoding of the\r\nsecond file in the For-Loops. With the second file decoded, we can actually write the file to disk with one line of\r\nPowerShell; that is, after the For-Loops, we can remove the remaining commands that load it into memory and use the\r\nfollowing command to write it to disk:\r\nSet-Content .backdoor.bin -Value $fileTwo -Encoding Byte\r\nWith that, we save the decoded file as “backdoor.bin” in our current working directory. As a Malware Analyst our remaining\r\ntask is to investigate the functionality of the binary. That will be in the second part of this blog post.\r\nAlternative Analysis Tips\r\nIn addition to what is written above, I completed additional analysis before writing the binary to file. I want to document\r\nthose activities as they may result in a quicker analysis than full script and binary analysis when a quicker analysis is needed\r\nby administrators or analysts.\r\nAs mentioned above, the binary is injected into memory by the script and is not written to file. These are the implications of\r\nthis:\r\nIf you do not have a method of flagging PowerShell execution or Memory Injection, the injected binary will go\r\nundetected,\r\nNo binary will be written to disk for static analysis. You will not have anything to upload to a service such as\r\nVirusTotal for quick verification and the scripts will not match anything on VirusTotal as they are custom in order to\r\npoint to your host’s user directory.\r\nYou will need to preform some type of dynamic analysis in order to identify the malware and activity that the\r\nmalware is performing.\r\nDynamic Analysis\r\nFor anyone unfamiliar, dynamic analysis refers to analyzing malware by running it. We will run the script in a virtual\r\nmachine disconnected from the internet and see what happens when it runs.\r\nhttps://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1/\r\nPage 3 of 5\n\nTwo easy tools for this are included in the Sysinternals Suite: Process Monitor (hereafter Procmon) and Process Explorer.\r\nProcmon monitors and logs registry, file, process, and thread activity. Process Explorer displays information on open\r\nProcesses and what threads and processes are opened by each process.\r\nFor running the malware, we are simply going to use the files provided for us by the Threat Actor: we will drop the script\r\nand encoded file onto our virtual machine and modify the Base64 in the script to point to the encoded file on our virtual\r\nmachine. (We can do that by decoding the Base64 in CyberChef, modifying the path, encoding the path to Base64 with\r\nCyberChef, and then putting the encoded path back into the script.).\r\nWith ProcessExplorer open and Procmon capturing events, we can run the script and identify what process ID it runs with. I\r\nran the script and saw a new “cmd.exe” process with a child process of “powershell.exe”. By hovering my mouse over it, I\r\nconfirmed that the command line to start this process was our malicious script. I can then see that the Process ID was 3888.\r\nclass=\r\nAn image of Process Explorer with the malicious script executed and the mouse hovering over the PowerShell\r\nprocess.\r\nI stopped Procmon capturing events and filtered Procmon to only include entries for Process ID 3888. After a few seconds\r\nand it still logged 13,000 events related to process. A majority of the events are common PowerShell events that aren’t\r\nimportant to analyzing our malware. To be honest, sifting through it is not an easy task.\r\nIn this instance, we are actually able to use the “Find” feature (Ctrl+F) to look for the name of the 2nd file. I’ve filtered out\r\nsome other operations, but what we find is that shortly after it access that second file, the process writes a file to disk called\r\n“solarmarker.dat”.\r\nclass=\r\nAn image with Procmon filtered and the solarmarker.dat WriteFile operation revealed.\r\nThe file is not intelligible if we open it, but this file a high value finding. It is a high value finding because the malware is\r\nnot using random strings anymore: the malware created a file with a static name “solarmarker.dat”.\r\nAn image of the contents of solarmarker.dat\r\nWith that name, we are able to Google and find anything that has been published about the malware. With that, I was able to\r\nidentify quickly what the malware was and the possible behaviors that may have been executed on the system. From this\r\npublished information, as an administrator, I have the most important information I need:\r\nThe solarmarker.dat is documented as a Host Identifier sent to the threat actor\r\nAny hosts with this file in that directory have been compromised with this malware and this malware may steal\r\npasswords\r\nWe can then take the appropriate action for our organization: removing the malware on compromised hosts and resetting\r\npasswords as deemed necessary.\r\nConclusion\r\nIn this Part 1, we’ve analyzed the malware script to understand what the script does, we have also done dynamic analysis in\r\nthe event that we cannot understand the script. The dynamic analysis gave us an important string allowing us to act fast on\r\nhttps://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1/\r\nPage 4 of 5\n\nconfirming an infection and gave us a direction for remediating the malware.\r\nIn Part 2, we will look at the binary that was injected into memory and analyze what we saved to disk.\r\nSource: https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1/\r\nhttps://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1/\r\nPage 5 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1/"
	],
	"report_names": [
		"mars-deimos-solarmarker-jupyter-infostealer-part-1"
	],
	"threat_actors": [],
	"ts_created_at": 1775434429,
	"ts_updated_at": 1775791275,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/dd11f95bff4d39a49fb78a1bb53965ef76de573b.pdf",
		"text": "https://archive.orkl.eu/dd11f95bff4d39a49fb78a1bb53965ef76de573b.txt",
		"img": "https://archive.orkl.eu/dd11f95bff4d39a49fb78a1bb53965ef76de573b.jpg"
	}
}