Linux Malware Analysis

From Ggl's wiki

Jump to: navigation, search

Contents

Introduction

Tools

  • qemu
  • qemu image filesystem
  • binutils
  • gdb
  • elfsh
  • maybe (depends on the malware complexity) IDA Pro (on x86, 4.3 freeware version can be used)
  • samhain
  • AIDE
  • md5sum
  • sha1sum
  • gnupg

other debugger (alternatives to gdb):

  • linice
  • the Dude
  • kdb
  • kgdb
  • pice (private ice)

Analysis

Now you have your toolz armory, you can begin to identify the malware. I'll focus on userland malware so I'll use gdb with mammon_'s configuration file.

  • First, do some hashes of it to identify the binary later:
md5sum malware
sha1sum malware
  • After you need to have a sandbox environnement. Install qemu and the target OS on it (for this example, I choose to install a debian sarge).
  • On debian :
apt-get install qemu
apt-get install debbootstrap
qemu-make-debian-root 1024 stable http://ftp.de.debian.org sandbox.qemu.img
note: qemu-make-debian-root [-k] size-in-MiB distrib deburl image [files-to-copy-in-/root]
  • Now, install samhain to monitor modification of the sandbox OS. You can also use AIDE to make a snapshot and to verify after.
apt-get install samhain
  • What are the main locations to monitor ?
/etc/, everything in $PATH and everything in /lib, /usr/lib. Don't forget /dev and /proc.
  • log onto the sandbox and begin to analyse the malware :
file malware
strings malware
  • If strings doesn't return anything interesting the binary is probably packed. If you have luck it's pack with a known packer/encrypter (upx, burneye, or shiva but shiva is difficult to analyse so no luck :p).

Session 1 - pbueno-06

  • download debian 3.1r1 iso
  • create qemu HD image :
qemu-img create -f qcow hd.img 1200M
  • start qemu to install image :
qemu -boot -d -cdrom ../files/debian31r1-i386-binary-1.iso -hda hd.img
  • <Enter> to start install
  • Configure timezone
  • Enter root password (testhostile)
  • Create unprivileged user (greg/zorglub)
  • Install base system
  • Additionnal packages to install :
    • vim
    • screen
    • samhain
    • gdb
    • binutils (strings, readelf, objdump)
    • elfsh
    • upx
    • unzip
    • hte
    • hexdump
    • strace
    • ltrace
aide -i (init db in /var/lib/aide)
aide -C (check the files with rules defined in /etc/aide/aide.conf)
  • no changes with unprivileged user
  • _0x01. Are these files packed? If so, which packer?
$ readelf -h shelll
[...]
 Entry point address:               0x8048e60
[...]
$ readelf -S shelll

There are 35 section headers, starting at offset 0x5aa8:

Section Headers:
 [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
 [ 0]                   NULL            00000000 000000 000000 00      0   0  0
 [ 1] .interp           PROGBITS        08048134 000134 000013 00   A  0   0  1
 [ 2] .note.ABI-tag     NOTE            08048148 000148 000020 00   A  0   0  4
 [ 3] .note.SuSE        NOTE            08048168 000168 000018 00   A  0   0  4
 [ 4] .hash             HASH            08048180 000180 000184 04   A  5   0  4
 [ 5] .dynsym           DYNSYM          08048304 000304 0003a0 10   A  6   1  4
 [ 6] .dynstr           STRTAB          080486a4 0006a4 0001cc 00   A  0   0  1
 [ 7] .gnu.version      VERSYM          08048870 000870 000074 02   A  5   0  2
 [ 8] .gnu.version_r    VERNEED         080488e4 0008e4 000030 00   A  6   1  4
 [ 9] .rel.dyn          REL             08048914 000914 000008 08   A  5   0  4
 [10] .rel.plt          REL             0804891c 00091c 0001b0 08   A  5  12  4
 [11] .init             PROGBITS        08048acc 000acc 000017 00  AX  0   0  4
 [12] .plt              PROGBITS        08048ae4 000ae4 000370 04  AX  0   0  4
 [13] .text             PROGBITS        08048e60 000e60 003184 00  AX  0   0 16
 [14] .fini             PROGBITS        0804bfe4 003fe4 00001a 00  AX  0   0  4
 [15] .rodata           PROGBITS        0804c000 004000 000e83 00   A  0   0  4
 [16] .eh_frame         PROGBITS        0804ce84 004e84 000004 00   A  0   0  4
 [17] .ctors            PROGBITS        0804d000 005000 000008 00  WA  0   0  4
 [18] .dtors            PROGBITS        0804d008 005008 000008 00  WA  0   0  4
 [19] .jcr              PROGBITS        0804d010 005010 000004 00  WA  0   0  4
 [20] .dynamic          DYNAMIC         0804d014 005014 0000c8 08  WA  6   0  4
 [21] .got              PROGBITS        0804d0dc 0050dc 000004 04  WA  0   0  4
 [22] .got.plt          PROGBITS        0804d0e0 0050e0 0000e4 04  WA  0   0  4
 [23] .data             PROGBITS        0804d1e0 0051e0 000100 00  WA  0   0 32
 [24] .bss              NOBITS          0804d2e0 0052e0 000690 00  WA  0   0 32
 [25] .comment          PROGBITS        00000000 0052e0 000173 00      0   0  1
 [26] .debug_aranges    PROGBITS        00000000 005458 000078 00      0   0  8
 [27] .debug_pubnames   PROGBITS        00000000 0054d0 000025 00      0   0  1
 [28] .debug_info       PROGBITS        00000000 0054f5 0001fa 00      0   0  1
 [29] .debug_abbrev     PROGBITS        00000000 0056ef 000076 00      0   0  1
 [30] .debug_line       PROGBITS        00000000 005765 00017c 00      0   0  1
 [31] .debug_str        PROGBITS        00000000 0058e1 000095 01  MS  0   0  1
 [32] .shstrtab         STRTAB          00000000 005976 000132 00      0   0  1
 [33] .symtab           SYMTAB          00000000 006020 000bd0 10     34  61  4
 [34] .strtab           STRTAB          00000000 006bf0 0007ee 00      0   0  1

Sections are all explicitly present and readable. Entry point is at the beginning of .text section. Thus,apt shelll is not packed. cmd.zip contains "cmd.gif" which is an "exported SGML document text". Actually it's a PHP script fully readable. Not packed.

  • _0x02. (a)- Without running the applications, identify what the malware can/will do, then [...]

shelll

strings shows some irc client commands :

NOTICE %s :Receiving file.
NOTICE %s :Saved as %s
NOTICE %s :Spoofs: %d.%d.%d.%d
NOTICE %s :Spoofs: %d.%d.%d.%d - %d.%d.%d.%d
NOTICE %s :Kaiten wa goraku
NOTICE %s :NICK <nick>
NOTICE %s :Nick cannot be larger than 9 characters.

shelll seems to be an irc bot.

The elf binary was compiled with full symbols and debug symbols. readelf -s shows network related symbols :

in .dynsym

14: 00000000   120 FUNC    GLOBAL DEFAULT  UND accept@GLIBC_2.0 (2)
16: 00000000    57 FUNC    GLOBAL DEFAULT  UND listen@GLIBC_2.0 (2)
19: 00000000   120 FUNC    GLOBAL DEFAULT  UND sendto@GLIBC_2.0 (2)
20: 00000000    57 FUNC    GLOBAL DEFAULT  UND setsockopt@GLIBC_2.0 (2)
28: 00000000    39 FUNC    GLOBAL DEFAULT  UND inet_addr@GLIBC_2.0 (2)
29: 00000000   836 FUNC    GLOBAL DEFAULT  UND inet_network@GLIBC_2.0 (2)
37: 00000000   407 FUNC    GLOBAL DEFAULT  UND gethostbyname@GLIBC_2.0 (2)
43: 00000000    14 FUNC    GLOBAL DEFAULT  UND htons@GLIBC_2.0 (2)
53: 00000000    57 FUNC    GLOBAL DEFAULT  UND socket@GLIBC_2.0 (2)

in .symtab

   58: 00000000     0 FILE    LOCAL  DEFAULT  ABS kaiten.c

tells that the malware might be a kaiten variant. Kaiten is a IRC DDoS Bot.

cmd.gif

cmd.gif is a PHP script used to execute command of a http server. It's part of a well known tool called "Defacing Tool Pro" (DTool).

  • _0x02. (b)- run the applications and identify additional details evident when the applications are run.
$ ./shelll
$

What happened ?

'ps' aux doesn't show shelll processes. 'pstree -p' or only 'ps' does :

$ pstree -p
[...]
   |--shelll(1019)
[...]


'killall shelll' kills all shelll processes.

Actually 'ps aux' show the command name '-bash' but in /proc/<pid>/ we see the real name of the process:

$ head -n 1 /proc/1019/status
Name:	shelll

and also /proc/1019/exe -> /mnt/hdb/shelll

Two ways to trace the execution of shelll : using strace/ltrace or using gdb.

ltrace shows an overview of library functions calls :

$ ltrace ./shelll
__libc_start_main(0x804b947, 1, 0xbffffb94, 0x804bf60, 0x804bef0 <unfinished ...>
fork()						= 1045
exit(o <unfinished ...>
+++ exited (status 0) +++
$ 

So, shelll starts a child with PID 1045.

$ gdb ./shelll
(gdb) b fork
Function "fork" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 2 (fork) pending.
(gdb) r
Starting program: /mnt/hdb/pbueno-ma6/shelll
[...]

Breakpoint 3, 0x400c2df6 in fork () from /lib/libc.so.6
(gdb) s
Single stepping until exit from function fork,
which has no line number information.
0x0804b96d in main ()
(gdb) p $eax
$1 = 1019

It's the return of the fork(), so it represents the PID of the child.

(gdb) s
Single stepping untiel exit form function main,
which has no line number information.

Program exited normally.
(gdb)

fork() was the last function to be called.

(gdb) attach 1019

[...]
(gdb) 0x400e9a98 in poll () from /lib/libc.so.6


In parallel, lsof shows shelll connecting to the fake dns server and try to connect to irc.ircnet.net :
$ lsof | grep shelll
[...]
shelll	1019	root	4u	IPv4	414041	UDP	10.0.2.15:4007->10.0.2.3:domain
shelll	1019	root	3u	sock	0,0		414039	can't identify protocol	
$ ls -l /proc/1019/fd shows to sockets :
3 -> socket:[414039]
4 -> socket:[414041]

tcpdump tells that shelll try to connect to irc.ircnet.net So I add :

127.0.0.1	irc.ircnet.net

to /etc/hosts

and start netcat to listen on port 6667/tcp

  • _0x05. Why didn't the 'shelll' or the 'cmd' applications show up at the ps aux ?

shelll was started with '-bash' as cmdline so ps aux display this name. pstree shows the real binary name (like /proc/<pid>/status Name field).

cmd is a php script so it is interpreted by apache from http request.

  • _0x06. Do you have any clues of how the machine was compromised ?

In secure.txt, there are a lot of Failed ssh authentication attempts :

 Feb 13 10:28:58 linux sshd[1446]: Failed password for invalid user mark from xxx.60.116.10 port 44242 ssh2
 Feb 13 10:28:58 linux sshd[1446]: Failed password for invalid user mark from xxx.60.116.10 port 44242 ssh2
 Feb 13 10:28:58 linux sshd[1446]: Received disconnect from xxx.60.116.10: 11: Bye Bye
 Feb 13 10:28:59 linux sshd[1446]: Invalid user mark from xxx.60.116.10
 Feb 13 10:29:00 linux sshd[1446]: reverse mapping checking getaddrinfo for 10-116-60-xxx.serverpronto.com failed - POSSIBLE BREAKIN ATTEMPT!

At the end of the file, the backup user authenticates :

 Feb 13 11:05:50 linux sshd[1446]: Accepted password for backup from xxx.60.116.1

0 port 20577 ssh2

And after used sftp :

 Feb 13 19:35:23 linux sshd[1446]: subsystem request for sftp
 Feb 13 19:51:44 linux sshd[1446]: Accepted password for backup from xxx.60.116.10 port 3635 ssh2

It may be a ssh brute-force attack.

What is backup's password :

$ /usr/sbin/john  backup 
Loaded 1 password (OpenBSD Blowfish [32/32])
backup           (backup)
guesses: 1  time: 0:00:00:00 100% (1)  c/s: 1.00  trying: backup

Ok so backup's password was trivial.

I guess that the host was compromised by this ssh brute-force attack and the backup user with password 'backup' was used to upload malwares.

Personal tools