███                   █████                          
            ░░░                   ░░███                           
 ████████   ████   █████   ██████  ░███████    ██████   █████ ████
░░███░░███ ░░███  ███░░   ███░░███ ░███░░███  ░░░░░███ ░░███ ░███ 
 ░███ ░███  ░███ ░░█████ ░███ ░░░  ░███ ░███   ███████  ░███ ░███ 
 ░███ ░███  ░███  ░░░░███░███  ███ ░███ ░███  ███░░███  ░███ ░███ 
 ████ █████ █████ ██████ ░░██████  ████ █████░░████████ ░░███████ 
░░░░ ░░░░░ ░░░░░ ░░░░░░   ░░░░░░  ░░░░ ░░░░░  ░░░░░░░░   ░░░░░███ 
                                                         ███ ░███ 
                                                        ░░██████  
                                                         ░░░░░░   
	

Backdoor.srvupdat.exe

Image describing the post

Description: Writeup for the binary Backdoor.srvupdat.exe

Introduction

I have been procrastinating on the PMAT course for months, and I finally decided to finish it this week somehow. This writeup is for the Backdoor.srvupdat.exe.malz file.

Without further ado, let’s just dive into it.

Setup and Initial Static Analysis

I’m using IDA for this writeup, but it should be easy enough to follow along with other disassemblers/decompilers that you are familiar with.

AlphaGolang’s categorization script has very nicely come up with folders for us to look into. Here’s a snippet:

image.png

One look at https://github.com/kardianos/service and we can immediately figure out that service has very little to do with our actual malware, but a lot to do with how it persists in the system. We can basically ignore all of the github_com_kardianos_service* functions.

The main function in golang is usually named main_main in IDA, so here’s a snippet of that: image.png

srv, srvgosse41sse42ssse3 and gosrv immediately stand out to me as weird, and it’s pretty interesting that it’s passed onto github_com_kardianos_service_New. Thankfully, there’s a simple example on the github page. Here’s the relevant snippet:

  func main() {
  	svcConfig := &service.Config{
  		Name:        "GoServiceExampleSimple",
  		DisplayName: "Go Service Example",
  		Description: "This is an example Go service.",
  	}
  
  	prg := &program{}
  	s, err := service.New(prg, svcConfig)

Okay, so the last argument is the svcConfig, which is presumably what the service will be called in Task Scheduler. There’s also the main_logger variable, which at first glance looks like it corresponds to the s.Logger(nil) line in the simple example.

If all this is true, there should be three functions named Start, Stop, and run right? As a matter of fact, there are, and they’re called main__program_Start, main__program_Stop, and main__program_run in the screenshots, respectively. So if I’m following the example program given, main__program_Start should simply be just go p.run(), and if you look at the disassembly, that is indeed the case:

image.png

So we have shown beyond a shred of doubt that the malware here follows the same basic program structure as the example program for service, which means that p.run() (or rather main__program_run) should have all the juicy details. And it does:

image.png

The very first line shows a GET request to http://ec2-3-109-20-24-srv3.local/favicon.ico, and then there’s a net.Dial, where the program clearly reads something out of it. If you’ve worked with metasploit or related shells enough, you know that the reverse shell usually connects to a remote IP and then does something with the input that it gets.

image.png

And there’s the telltale sign that it’s indeed a shell, it executes something based on what I give as input.

So all I really need to do is to figure out what it’s connecting to, where the assembly of the net.Dial call comes in handy:

image.png

So all I need to do is to assign my VM the IP 10.10.1.237, start a listener at port 3301, and we should have a reverse shell.

image.png

And that’s exactly what happens.

Contact me