Linux Sistemlerde Zararlı Yazılım Analizi – Temel Seviye Dinamik Analiz

Temel seviye dinamik analizde zararlı çalıştırılarak ağ, dosya sistemi, süreçler ve diğer işletim sistemi bileşenleri üzerindeki etkileri gözlemlenir. Zararlının çalıştığı sistemde ve ağda kalıcı etkileri olabileceğinden dolayı dinamik analizin izole bir ortamda yapılması önerilir. Örneklere “Temel Seviye Statik Analiz” (http://blog.bga.com.tr/2014/12/linux-sistemlerde-zararl-yazlm-analizi.html) yazısında kullanılan zararlı ile devam edilmiştir.

Zararlı çalıştırıldığında “ps” komutu ile sistem süreçleri listelenir, “-ef” parametreleri verilerek süreçlerin PPID (parent process id) gibi detayları da listelenir. Bu sayede grep komutunun da yardımı ile dosya isminden yola çıkarak ilk süreç, ilk sürecin PID değerinden yola çıkarak da başlattığı diğer süreçler bulunur.

ps -ef |grep elknot |grep -v grep
remnux    1702     1  0 04:00 ?        00:00:00 ./elknot

ps -ef|grep 1702|grep -v grep
remnux    1702     1  0 04:00 ?        00:00:00 ./elknot

ps çıktısında zararlının başlattığı başka bir süreç bulunmadığı görülüyor.

Daha sonra “strace” komutuyla sürecin yaptığı sistem çağrıları izlenir. Bu sayede yaptığı işlemler hakkında oldukça fazla bilgi edinilebilir.

strace ./elknot
execve(“./elknot”, [“./elknot”], [/* 44 vars */]) = 0
…..
readlink(“/proc/1851/exe”, “/home/remnux/Desktop/elknot”, 1024) = 27
stat64(“/home/remnux/Desktop/elknot”, {st_mode=S_IFREG|0755, st_size=1223123, …}) = 0
getppid()                               = 1850
readlink(“/proc/1850/exe”, “/usr/bin/strace”, 255) = 15
readlink(“/proc/1851/exe”, “/home/remnux/Desktop/elknot”, 1024) = 27
readlink(“/proc/1851/exe”, “/home/remnux/Desktop/elknot”, 1024) = 27
readlink(“/proc/1851/exe”, “/home/remnux/Desktop/elknot”, 1024) = 27
readlink(“/proc/1851/exe”, “/home/remnux/Desktop/elknot”, 1024) = 27
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x9476878) = 1852
exit_group(0)                           = ?

Örnekte zararlı çalışmasını “fork” ile dallandırdığı için “strace” çıktısı faydalı bir bilgi sağlamıyor. Böyle durumlarda fork edilen süreçleri de takip etmek için “-f” parametresi kullanılır.

strace -f ./elknot
….
open(“/dev/null”, O_RDWR)               = 3
fstat64(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), …}) = 0
dup2(3, 0)                              = 0
dup2(3, 1)                              = 1
dup2(3, 2)                              = 2
close(3)                                = 0
open(“/tmp/”, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY) = 3
fstat64(3, {st_mode=S_IFDIR|S_ISVTX|0777, st_size=4096, …}) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
getdents64(3, /* 14 entries */, 4096)   = 496
getdents64(3, /* 0 entries */, 4096)    = 0
close(3)                                = 0
nanosleep({1, 0}, NULL)                 = 0
open(“/tmp/moni.lod”, O_RDWR)           = -1 ENOENT (No such file or directory)
nanosleep({1, 0}, NULL)                 = 0
open(“/tmp/bill.lock”, O_RDWR)          = -1 ENOENT (No such file or directory)
unlink(“/tmp/bill.lock”)                = -1 ENOENT (No such file or directory)
access(“/tmp/gates.lod”, F_OK)          = 0
open(“/tmp/gates.lod”, O_RDWR)          = 3

flock(3, LOCK_EX|LOCK_NB)               = 0
flock(3, LOCK_UN)                       = 0
close(3)                                = 0
access(“/tmp/gates.lod”, F_OK)          = 0
open(“/tmp/gates.lod”, O_RDWR)          = 3

…..
Process 1898 resumed (parent 1897 ready)
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7768938) = 1898
[pid  1898] execve(“/sbin/insmod”, [“insmod”, “/home/remnux/Desktop/xpacket.ko”], [/* 44 vars */]) = 0
[pid  1898] brk(0)                      = 0x81a9000
[pid  1898] access(“/etc/ld.so.nohwcap”, F_OK) = -1 ENOENT (No such file or directory)
[pid  1898] mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb779a000

[pid  1907] socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4
[pid  1907] setsockopt(4, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
[pid  1907] setsockopt(4, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0

[pid  1907] time(NULL)                  = 1419240360
[pid  1907] fcntl64(4, F_GETFL)         = 0x2 (flags O_RDWR)
[pid  1907] fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
[pid  1907] connect(4, {sa_family=AF_INET, sin_port=htons(25000), sin_addr=inet_addr(“23.251.63.37”)}, 16) = -1 EINPROGRESS (Operation now in progress)
[pid  1907] fcntl64(4, F_GETFL)         = 0x802 (flags O_RDWR|O_NONBLOCK)
[pid  1907] fcntl64(4, F_SETFL, O_RDWR) = 0
[pid  1907] getsockname(4, {sa_family=AF_INET, sin_port=htons(41238), sin_addr=inet_addr(“172.16.63.160”)}, [16]) = 0
[pid  1907] open(“/home/remnux/Desktop/conf.n”, O_RDWR|O_CREAT, 0644) = 5
[pid  1907] flock(5, LOCK_EX)           = 0
[pid  1907] write(5, “E”, 4)      = 4
[pid  1907] write(5, “36410023503112”…, 69) = 69

[pid  1907] flock(5, LOCK_UN)           = 0
[pid  1907] close(5)                    = 0
[pid  1907] open(“/proc/net/route”, O_RDONLY) = 5

Çıktı yorumlandığında zararlının dikkate değer aktiviteleri şu şekilde sıralanabilir:

  • /tmp dizini altında bill veya gates ile başlayan dosyaları açmaya çalışıyor.
  • xpacket.ko isimli bir kernel modülü yüklemeye çalışıyor.
  • 23.251.63.37 IP’sinin 25000’inci portuna bir TCP bağlantısı açıyor.
  • Çalıştığı dizinde “conf.n” isimli bir dosya oluşturup içine bir takım değerler yazıyor.

Strace’in yanısıra “ltrace” komutuyla zararlının harici kütüphanelere yaptığı çağrılar takip edilebilir.

ltrace ./elknot
ltrace: Couldn’t find .dynsym or .dynstr in “./elknot”

Örnek zararlı harici kütüphaneleri statik olarak bağladığı için (static linking) ltrace başarılı olamamıştır.

Süreçlerin ağ bağlantıları ve hangi aşamada oldukları bilgisine “netstat” komutula ulaşılır, buna alternatif olarak lsof komutu da kullanılabilir. Örneğin, TCP bağlantıları ve bağlantıyı açan süreç “-tp” parametreleriyle görüntülenir. İstenilirse “-n” parametresi eklenerek reverse dns çözümlemesi yapılması engellenir.  Süreç isimlerini ve tüm bağlantıları listeleyebilmek için komutu tam yetkili olarak çalıştırmak gerekir.

sudo netstat -ntp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      1 172.16.63.160:41218     23.251.63.37:25000      SYN_SENT    1702/elknot  

Strace çıktısında görülen bağlantı netstat ile de doğrulanmıştır. State değerinin “SYN_SENT” olması bağlantı açma isteğinin sunucuya gönderildiği ancak henüz cevap dönmediği anlamına gelir. Başarıyla açılan bir bağlantıda bu değer “ESTABLISHED” olarak değişecektir.

Ağ trafiğinin detaylı analizi, “Zararlı Yazılım Trafiğinin Sahte Servislerle Yönetimi” (http://blog.bga.com.tr/2014/02/zararl-yazlm-trafiginin-sahte.html) ve  “SSL Kullanan Zararlı Yazılımın Trafiğini Yönlendirme ve İnceleme” (http://blog.bga.com.tr/2014/04/ssl-kullanan-zararl-yazlmn-trafigini.html) yazılarında anlatıldığı gibi yapılabilir.

Her ne kadar bu yazılarda hedef sistem Windows olsa da, linux için farklılık gösteren tek bölüm trafiğin yönlendirilme kısmıdır. Mesela DNS isteklerine sahte cevaplar vererek trafiği yönlendirmek için “fakedns” aracı kullanılabilir. Tüm DNS isteklerine 10.10.10.10 cevabını dönmek için:

sudo fakedns 10.10.10.10
pyminifakeDNS:: dom.query. 60 IN A 10.10.10.10
Respuesta: google.com. -> 10.10.10.10

Tüm trafiği 10.10.10.10 makinesi üzerinden yönlendirmek için:

sudo route add default gw 10.10.10.10

route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.10.10.10     0.0.0.0         UG    0      0        0 eth1
0.0.0.0         172.16.63.2     0.0.0.0         UG    100    0        0 eth0
172.16.63.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

Komut ve parametreleri kullanılır.