hello world; echo from Divya!

I read and write but never execute. A cs major in cool pajamas. Alias rachejazz OR h3ck

DM me on Twitter Checkout my GitHub View My Resume Back to Portfolio
3 March 2020 Back to Blogs list

Malware Analysis using Radare2

by Divya

Breaking down infections for fun. Exploring r2 while breaking down the first ever discovered malware for Apple M1 chips.

Brief intro

Malware has been a predominant threat to computers, networks, and infrastructures for decades now. Detecting these pieces of nuisances has been an ordeal as malware analysts are coming about with new and improvised ways to detect and nip them in the bud before they create destruction.

Discovering newly designed ones in the Wild

Detecting previously attacked malware can be easy based on signature or anomaly. Storing their signature in databases, developing rules based on typical behaviours of such malicious code has been proved efficient thus far.

What about the newer ones?

Noticing weird behaviour in your system? Get the app, we are going to do some reversing today.

I will be using the newest and the first malware discovered in the wild for Apple M1 Chips :) Details about the malware can be found here (Thanks to virustotal!): GoSearch22


As you can now see GoSearch is an “adware”, meaning it is capable of hijacking the settings of the mac device and causes automatic redirection to specific webpages. Works for all major browsers(Like Safari, Firefox, Chrome). Watch carefully the /details section to get a quick view of what it is (more revealed to you in this blog)

For the more curious ones, feel free to continue to the graph feature where you will get a better representation of the calls made by the file.


First things first. Verify what type of file do we have here:

┬─[divya at racharch in ~/a/b/r/mldt]
╰──> λ file sample
sample: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>] [arm64:Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>]

[Note: If you were curious about what universal binaries are: We can be friends!]

We have our sample. Let’s start exploring

┬─[divya at racharch in ~/a/b/r/mldt]
╰──> λ r2 sample 
 -- what happens in #radare, stays in #radare
[0x100001d20]>
[0x100001d20]> ?
Usage: [.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ...
Append '?' to any char command to get detailed help
Prefix with number to repeat command N times (f.ex: 3x)
| %var=value              alias for 'env' command
| *[?] off[=[0x]value]    pointer read/write data/values (see ?v, wx, wv)
| (macro arg0 arg1)       manage scripting macros
| .[?] [-|(m)|f|!sh|cmd]  Define macro or load r2, cparse or rlang file
Truncated

[Note: Again, if ever in doubt on the command, go ahead and see what aa? says about it.]

[0x100001d20]>aaaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Parsing metadata in ObjC to find hidden xrefs
[x] Found 0 objc xrefs in 122 dwords.
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[x] Finding function preludes
[x] Enable constraint types analysis for variables
[0x100001d20]> #done!

[Note: This might not be a thorough tutorial of r2, I will be walking through the useful ones. You can always find more on r2book]

[0x100001d20]> iI?
| iI                 Binary info
[0x100001d20]> iI
arch     x86
baddr    0x100000000
binsz    414368
bintype  mach0
bits     64
canary   true
Truncated

We are done with our first scan on GoSearch using r2!

[0x100001d20]> afl?
Usage: afl   List all functions
| afl            list functions
| afl.           display function in current offset (see afi.)
| afl+           display sum all function sizes
[0x100001d20]> afl
0x100001d20   90 4333         entry0
0x100053410    1 6            sym.imp.CC_MD5
0x100053416    1 6            sym.imp.CGEventSourceSecondsSinceLastEventType
Truncated


We see the exports using e(for entrypoints) and E(for exports).

[0x100001d20]> iE?
| iE                 Exports (global symbols)
| iE.                Current export
[0x100001d20]> ie?
| ie                 Entrypoint
| iee                Show Entry and Exit (preinit, init and fini)
[0x100001d20]> ieE
[Entrypoints]
vaddr=0x100001d20 paddr=0x00002d20 haddr=0x000009b8 type=program

1 entrypoints
[Exports]

nth paddr       vaddr       bind   type size lib name
―――――――――――――――――――――――――――――――――――――――――――――――――――――
0    0x00001000 0x100000000 GLOBAL FUNC 0        __mh_execute_header

For viewing imports or API calls to different locations of the system, we use i.

[0x100001d20]> ii?
| ii                 Imports
[0x100001d20]> ii
[Imports]
nth vaddr       bind type           lib name
――――――――――――――――――――――――――――――――――――――――――――
0   0x100053410 NONE FUNC               CC_MD5
1   0x100053416 NONE FUNC               CGEventSourceSecondsSinceLastEventType
Truncated

Demo 1

There are several things you can do with r2. As we are done with a basic info gathering around our sample. We can now try walking around different areas and see in detail what a section of the code looks like. Seek command or s is made exactly for this. Viewing at the different API calls we select one and move to the section where it is actually imported.

[0x100001d20]> s?
Usage: s    # Help for the seek commands. See ?$? to see all variables
| s                 Print current address
| s.hexoff          Seek honoring a base from core->offset
| s:pad             Print current address with N padded zeros (defaults to 8)
| s addr            Seek to address
[0x100001d20]> ii~IOServiceMatching
6   0x100053434 NONE FUNC               IOServiceMatching
[0x100001d20]> s 0x100053434
[0x100053434]> #seek address changed!

Notice the change in the seek pointer? Now we are at the point of the code where the IOServiceMatching API is geting called. How do we know? It is dissassembly time!

[0x100053434]> pd?
Usage: p[dD][ajbrfils] [len]   # Print Disassembly
| NOTE: len        parameter can be negative
| NOTE:            Pressing ENTER on empty command will repeat last print command in next page
| pD N             disassemble N bytes
| pd -N            disassemble N instructions backward
| pd N             disassemble N instructions
| pd--[n]          context disassembly of N instructions
Truncated

Demo 2

At this point, you are now capable to explore different areas of a binary, watch function calls/print statements, stare at funny looking symbols like rax, rsi, rbi,etc (if you do not find them funny, there’s something for you in the next section.) Radare2 offers a visual mode with v command. With different commands viewed on each panel, analyzing becomes easier. It supports navigating with both mouse and keyboard. Cool isn’t it?
Visual Panel Mode: Hit <Shift>+<"> keys to see what more you can see other than the default. If you are interested in reading x86, I strongly recommend you to go through options of viewing Registers, RegRefs, Disassembly summary.

Yet another feature of r2 is viewing whole binary in form of a graph with all functions calls chalked out in asciiart. Hit VV to enter graphical mode. Each node is labeled with a series of [a-z], simply type the sequence to select and view that node.


Digging into the binary, r2 commandlinefu

[0x198e3e6e3]> iz?
| iz|izj             Strings in data sections (in JSON/Base64)
| izz                Search for Strings in the whole binary
| izzz               Dump Strings from whole binary to r2 shell (for huge files)
| iz- [addr]         Purge string via bin.str.purge
[0x198e3e6e3]> iz
[Strings]
nth paddr      vaddr       len size section                   type  string
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
0   0x0005379e 0x10005379e 7   10   3.__TEXT.__const          utf8  ZQ6J\bԳߛ blocks=Basic Latin,Armenian,NKo
1   0x000537fc 0x1000537fc 4   6    3.__TEXT.__const          utf8  ]\n blocks=Basic Latin,Syriac
2   0x000538b2 0x1000538b2 4   5    3.__TEXT.__const          ascii 1lAW
3   0x000538d2 0x1000538d2 6   7    3.__TEXT.__const          ascii |\rSIy
4   0x000538f6 0x1000538f6 4   7    3.__TEXT.__const          utf8  '顇(Z blocks=Basic Latin,CJK Unified Ideographs
5   0x000539d2 0x1000539d2 4   5    3.__TEXT.__const          ascii 3y{m
6   0x00053a0c 0x100053a0c 5   7    3.__TEXT.__const          utf8  |` ;ݲ blocks=Basic Latin,Arabic Supplement
7   0x00053a5a 0x100053a5a 4   5    3.__TEXT.__const          ascii [wMm
8   0x00053a7d 0x100053a7d 4   5    3.__TEXT.__const          ascii ]i6j
9   0x00053ab0 0x100053ab0 4   5    3.__TEXT.__const          ascii jjQ$

Use ~<string> with iz to search for specific areas where the string is present. Now since we are analyzing a MacOS application (and me being too poor to posses a Mac), shouldn’t we have a basic idea of the file hierarchy?

Ladies and Gentlemen, this is when Google autosuggestions saves your hardwork of browsing articles

There’s lot to find out using the iz command:

[0x100001d20]> iz~application
92  0x00055dd8 0x100055dd8 27  28   4.__TEXT.__objc_methname  ascii applicationShouldTerminate:
93  0x00055df4 0x100055df4 21  22   4.__TEXT.__objc_methname  ascii application:openURLs:
94  0x00055e0a 0x100055e0a 21  22   4.__TEXT.__objc_methname  ascii application:openFile:
95  0x00055e20 0x100055e20 22  23   4.__TEXT.__objc_methname  ascii application:openFiles:
96  0x00055e37 0x100055e37 25  26   4.__TEXT.__objc_methname  ascii application:openTempFile:
97  0x00055e51 0x100055e51 34  35   4.__TEXT.__objc_methname  ascii applicationShouldOpenUntitledFile:
98  0x00055e74 0x100055e74 28  29   4.__TEXT.__objc_methname  ascii applicationOpenUntitledFile:
99  0x00055e91 0x100055e91 30  31   4.__TEXT.__objc_methname  ascii application:openFileWithoutUI:
[0x100001d20]> izz~http
3253 0x00060f43 0x100060f43 30  31                             ascii   http://crl.apple.com/root.crl0
3272 0x0006135d 0x10006135d 31  32                             ascii   https://www.apple.com/appleca/0
3296 0x00061828 0x100061828 38  39                             ascii   $http://ocsp.apple.com/ocsp03-devid060
3298 0x00061943 0x100061943 44  45                             ascii   *http://www.apple.com/certificateauthority/0
3311 0x00061c63 0x100061c63 280 281                            ascii   <?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE
plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist
version="1.0">\n<dict>\n\t<key>cdhashes</key>\n\t<array>\n\t\t<data>\n\t\t8eww0u7pc24HrxN+85hMK8UnB3g=\n\t\t</data>\n\t</array>\n</dict>\n</plist>\n0\r
3334 0x000621e2 0x1000621e2 29  30                             ascii   http://www.apple.com/appleca0
3337 0x000622ee 0x1000622ee 36  37                             ascii   "http://crl.apple.com/timestamp.crl0
3363 0x0006270c 0x10006270c 30  31                             ascii   http://crl.apple.com/root.crl0
3381 0x00062b26 0x100062b26 31  32                             ascii   https://www.apple.com/appleca/0

I kept the best for the last.

Now as we may all love command line (probable reason why you are reading about r2 and not IDA), but hold your horses, r2 has a web interface too! And you do not need cutter for that!

Use =? to find out what more instances can r2 connect to

[0x100001d20]> =?
Usage:  =[:!+-=ghH] [...]   # connect with other instances of r2
remote commands:
| =                             list all open connections
| =<[fd] cmd                    send output of local command to remote fd
| =[fd] cmd                     exec cmd at remote 'fd' (last open is default one)
| =! cmd                        run command via r_io_system
| =+ [proto://]host:port        connect to remote host:port (*rap://, raps://, tcp://, udp://, http://)
| =-[fd]                        remove all hosts or host 'fd'
| ==[fd]                        open remote session with host 'fd', 'q' to quit
| =!=                           disable remote cmd mode

A basic http web interface can be stirred up using =H flag

┬─[divya at racharch in ~/a/b/r/mldt]
╰──> λ r2 -AA -c =H  sample
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Parsing metadata in ObjC to find hidden xrefs
[x] Found 0 objc xrefs in 122 dwords.
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[x] Finding function preludes
[x] Enable constraint types analysis for variables
Starting http server...
open http://localhost:9090/
r2 -C http://localhost:9090/cmd/

R2 Web interface. Check these out!

Binary Info from iI


Debugger(I will cover it sometime later)


Ending Note

As said earlier, covering the glory of this open source reversing tool in just one article will be too shameful. If you are interested in reversing and want to know more about r2, I will drop down various source links. That includes macOs file system info and many more! If you find any errors in this article, make sure to contact me(See bottom of page).

[Sources]