Threat Level: green Handler on Duty: Didier Stevens

SANS ISC: Internet Storm Center - SANS Internet Storm Center Internet Storm Center


Sign Up for Free!   Forgot Password?
Log In or Sign Up for Free!

Latest Diaries

Introduction to analysing Go binaries

Published: 2019-03-22
Last Updated: 2019-03-22 16:13:46 UTC
by Remco Verhoef (Version: 1)
0 comment(s)

Golang is gaining popularity by malware authors, and more golang based malware is being found in the wild. It is also one of my favourite programming languages, especially for all network related applications, for the reasons of:

  • the language syntax itself is simple, but you can do everything with it
  • binaries are being compiled statically, no need to install libraries
  • support for many operating systems and architectures
  • statically typed
  • goroutines (light weight threads)
  • channels (pipes using which goroutines communicate)

And my most important reason is that code I've created years ago, still compiles without the need to update or refactor the code to the newer compilers and language versions.  

Due the popularity of Golang by malware authors, we need more often to analyse these binaries and they are a bit different. Let me give you some primers.

Let's start first with a Hello World Golang application first, to give you an idea about the language and the structure.

package main

import "fmt"

func main() {
        fmt.Println("Hello World")
}

It starts with a package name, all files in the same folder will have the same package name. In this case main. Next we'll configure the imports, in this case the fmt library. Go is very struct and only allows imports that are being used. The main entry point is always called main. Now the code can be compiled for different architectures using the following command:

$ GOOS=linux GOARCH=amd64  go build -o hello ./hello.go 

 

Go compiled binaries are large, the Hello World example in this case is 1.9M. Now we know the basics, we can start analysing a real malware named sshd, which someone delivered kindly to our honeypots. Because of the large binaries, upx is being used often to suppress the file size. By default upx compress files can be decompressed using:

$ upx -d ./sshd 

 

When loading the binary into your favourite disassembler, you'll find many functions and strings. Most of those functions and strings are from default Go packages. If you have an address of a function start, the golang tool addr2line will come in handy. Addr2line uses the gopclntab section to retrieve data about the original function name, source file and locations. You'll probably encounter cases where the location of the source file contains the username in its path. 

$ echo "0x0062cd40" | go tool addr2line ./sshd
main.main
/root/go/src/sshcrack/sshcrack.go:184

 

There is also objdump which will output symbols and source locations together with assembly code if possible:

$ go tool objdump -s main ./vv 
...

  vv.go:321             0x6128e5                e8b6e9ffff              CALL main.post(SB)
  vv.go:321             0x6128ea                488b442418              MOVQ 0x18(SP), AX
  vv.go:321             0x6128ef                488b4c2420              MOVQ 0x20(SP), CX
  vv.go:322             0x6128f4                48890424                MOVQ AX, 0(SP)
  vv.go:322             0x6128f8                48894c2408              MOVQ CX, 0x8(SP)
  vv.go:322             0x6128fd                e86ee7ffff              CALL main.rsaDecrypt(SB)
  vv.go:322             0x612902                488b442410              MOVQ 0x10(SP), AX
  vv.go:322             0x612907                488b4c2418              MOVQ 0x18(SP), CX
  vv.go:323             0x61290c                48890424                MOVQ AX, 0(SP)
  vv.go:323             0x612910                48894c2408              MOVQ CX, 0x8(SP)
  vv.go:323             0x612915                e896feffff              CALL main.jsonload(SB)
  vv.go:323             0x61291a                488d742410              LEAQ 0x10(SP), SI
  vv.go:323             0x61291f                488d7c2440              LEAQ 0x40(SP), DI
...

 

Strings in the binary are not null terminated, but instead all concatenated to long strings. When strings are being referenced to, a following instruction will load the length. The instruction lea rax, ... loads the string reference, where the following instructions defines the length of the string to load, in this case 7 and makes it the string /bin/sh. In later Golang version this has been changed, as I believe, which I'll get back to in a later post.

 

Objects are being instantiated using runtime_newobject, taking a structure pointer as argument. The definition of the struct is being defined in the .typelink section of the binary. 

 

Version information in the binary can be found by searching for go1, which function runtime_schedinit references to. 

 

The call to sym.runtime.morestack_noctxt will resize the stack, as Go makes use of resizable stacks, then it will return to the start of the function, this pattern marks also the end and start of the function. 

 

This was just a quick overview of Golang binaries, more to follow. Please share your ideas, comments and/or insights, with me via social media, @remco_verhoef or email, remco.verhoef at dutchsec dot com. Have a great day!

Remco Verhoef (@remco_verhoef)
ISC Handler - Founder of DutchSec
PGP Key

Keywords:
0 comment(s)

If you have more information or corrections regarding our diary, please share.

Recent Diaries

New Wave of Extortion Emails: Central Intelligence Agency Case
Mar 21st 2019
2 days ago by Xme (4 comments)

Using AD to find hosts that aren't in AD - fun with the [IPAddress] construct!
Mar 20th 2019
3 days ago by Rob VandenBrink (0 comments)

Wireshark 3.0.0 and Npcap: Some Remarks
Mar 18th 2019
4 days ago by DidierStevens (1 comment)

Video: Maldoc Analysis: Excel 4.0 Macro
Mar 17th 2019
5 days ago by DidierStevens (0 comments)

Maldoc: Excel 4.0 Macros
Mar 16th 2019
6 days ago by DidierStevens (4 comments)

View All Diaries →

Latest Discussions

Run Extracted binaries from mirror traffic on cuckoo
created Feb 6th 2019
1 month ago by ching (1 reply)

Another sextortion email
created Feb 5th 2019
1 month ago by Anonymous (0 replies)

Two-factor authentication: Why do I need it? What are the best apps?
created Jan 27th 2019
1 month ago by Russell (0 replies)

sextortion Mail
created Jan 10th 2019
2 months ago by Anonymous (0 replies)

Internet security needed!
created Jan 3rd 2019
2 months ago by Anonymous (0 replies)

View All Forums →

Latest News

View All News →

Top Diaries

Wide-scale Petya variant ransomware attack noted
Jun 27th 2017
1 year ago by Brad (6 comments)

Using a Raspberry Pi honeypot to contribute data to DShield/ISC
Aug 3rd 2017
1 year ago by Johannes (13 comments)

Second Google Chrome Extension Banker Malware in Two Weeks
Aug 29th 2017
1 year ago by Renato (0 comments)

Detection Lab: Visibility & Introspection for Defenders
Dec 15th 2017
1 year ago by Russ McRee (2 comments)

Maldoc with auto-updated link
Aug 17th 2017
1 year ago by Xme (2 comments)